Извлечение непрерывных значений ячеек из нескольких файлов Excel с помощью Python

Цель моей задачи — во-первых, извлечь значения из непрерывных ячеек одного файла Excel. Затем тот же метод извлечения будет применен к остальным файлам Excel в той же папке, пока цикл не завершится

Например,
Я хочу извлечь значения из строки «A283:A9000» в файле Excel 1. После завершения извлечения в файле Excel 1 будет извлечено значение из строки «A283:A9000» в файле Excel 2, а затем извлечение в том же файле. строки «A283:A9000» будут продолжены в файле Excel 3, файле Excel 4, файле Excel 5 и так далее.

Я узнаю, как извлекать значения из нескольких файлов Excel из https://thewikihow.com/video_M7YkQpcB4fg Код работает хорошо, когда извлекаются значения из прерывистых ячеек. Однако, когда я пытаюсь использовать код для извлечения значения из непрерывных ячеек ('A283:A9000') одного и того же листа, код терпит неудачу.

Я знаю, что проблема возникает, когда я пытаюсь использовать код для извлечения значений из непрерывных ячеек одного и того же листа, но я не уверен, как исправить код в моем случае. Я думаю, что проблема заключается в строке (ячейки = ['C11', 'C15', 'D15', 'C16', 'A283:A9000']).

Может ли кто-нибудь помочь мне?

Ваше здоровье

Вот код, который я пробовал.

import os
import openpyxl 

folder = r'C:\PhD study\GIS\Wind_Downscale\test_one'
output_file = 'C:\PhD study\GIS\Wind_Downscale\Wind_data_forecast_time.xlsx'

output_wb = openpyxl.Workbook()
output_sheet = output_wb.active
output_sheet.title = 'Wind Data for Forecast Time'

cells = ['C11', 'C15', 'D15', 'C16', 'A283:A9000']

for filename in os.listdir(folder):
    if filename.endswith('.xlsx'):
        
        file = os.path.join(folder, filename)
        
        workbook = openpyxl.load_workbook(file)
       
   
        values = [workbook.active[cell].value for cell in cells]

        
        output_sheet.append(values)
        
output_wb.save(output_file)

Вот сообщение об ошибке:

Traceback (most recent call last):

File C:\\Conda5\\lib\\site-packages\\spyder_kernels\\py3compat.py:356 in compat_exec
exec(code, globals, locals)

File c:\\users\\kxz237.spyder-py3\\temp.py:29
values = \[workbook.active\[cell\].value for cell in cells\]

File c:\\users\\kxz237.spyder-py3\\temp.py:29 in \<listcomp\>
values = \[workbook.active\[cell\].value for cell in cells\]

AttributeError: 'tuple' object has no attribute 'value'

🤔 А знаете ли вы, что...
Python поддерживает множество парадигм программирования, включая процедурное, объектно-ориентированное и функциональное программирование.


1
71
2

Ответы:

Я не знаю, есть ли в openpyxl метод чтения из диапазонов ячеек (то, что вы называете непрерывными ячейками), который может быть быстрее. Однако обратите внимание, что ваш диапазон ячеек также может быть представлен списком адресов отдельных ячеек. Поэтому, если вы сначала используете понимание списка для создания списка этих отдельных адресов ячеек, это должно сработать.

Попробуйте заменить эту строку в своем коде:

cells = [f"A{i}" for i in range(283, 9000+1)]

Это создаст список типа ['A283', 'A284'... 'A9000']

Итак, все в вашем примере (при условии, что вам на самом деле не нужны эти начальные ячейки «C11», «C15», «D15», «C16» в вашем списке) будет...

import os
import openpyxl 

folder = r'C:\PhD study\GIS\Wind_Downscale\test_one'
output_file = 'C:\PhD study\GIS\Wind_Downscale\Wind_data_forecast_time.xlsx'

output_wb = openpyxl.Workbook()
output_sheet = output_wb.active
output_sheet.title = 'Wind Data for Forecast Time'

cells = [f"A{i}" for i in range(283, 9000+1)]

for filename in os.listdir(folder):
    if filename.endswith('.xlsx'):
        
        file = os.path.join(folder, filename)
        
        workbook = openpyxl.load_workbook(file)
       
   
        values = [workbook.active[cell].value for cell in cells]

        
        output_sheet.append(values)
        
output_wb.save(output_file)

Решено

Да, вы пытаетесь использовать «A283: A9000» в качестве координаты одной ячейки, отсюда и ошибка атрибута.

Альтернативой является то, что вы можете рассматривать каждый элемент списка ячеек как диапазон
cells = ['C11', 'C15', 'D15', 'C16', 'A283:A9000']
поэтому для каждого элемента код извлекает все ячейки, которые охватывает диапазон;
для «C11» это будет просто «C11»
для «A283:A9000» это будет «A283», «A284», «A285», «A286», ...

Используйте утилиту Openpyxl openpyxl.utils.cell.cols_from_range(<cells element>) для каждого элемента в списке ячеек.

import os
import openpyxl 

folder = r'C:\PhD study\GIS\Wind_Downscale\test_one'
output_file = 'C:\PhD study\GIS\Wind_Downscale\Wind_data_forecast_time.xlsx'

output_wb = openpyxl.Workbook()
output_sheet = output_wb.active
output_sheet.title = 'Wind Data for Forecast Time'

cells = ['C11', 'C15', 'D15', 'C16', 'A283:A9000']

for filename in os.listdir(folder):
    if filename.endswith('.xlsx'):
        file = os.path.join(folder, filename)

        workbook = openpyxl.load_workbook(file)

        #values = [workbook.active[cell].value for cell in cells]

        for rng in cells:  # Each element in 'cells' list 
            ### Get all cells in the elements range
            for allcells in openpyxl.utils.cell.cols_from_range(rng):
                ### allcells is a tuple of all individual cells in the range rng
                for cell in allcells:  # Extract each cell
                    values = workbook.active[cell].value

                    output_sheet.append([values])

output_wb.save(output_file)

Дополнительная информация к вашему сведению
Существует две утилиты Openpyxl, которые возвращают отдельные ячейки диапазона
openpyxl.utils.cell.cols_from_range(range_string) и
openpyxl.utils.cell.rows_from_range(range_string)

В этом сценарии можно использовать любой из них, учитывая, что указанный диапазон составляет всего один столбец.
Однако, если ваш диапазон охватывает два или более столбцов, каждый из них будет возвращать отдельные ячейки;
cols_from_range, ячейка из каждой строки вниз по первому столбцу, затем то же самое вниз по следующему столбцу и т. д. rows_from_range, ячейки во всех столбцах первой строки, затем все ячейки во всех столбцах второй строки и т. д.

то есть вернется диапазон «C3:D4»
cols_from_range, 'C3', 'C4', 'D3', 'D4'
rows_from_range, 'C3', 'D3', 'C4', 'D4'