Python - openpyxl читает данные xlsx после записи в существующий xlsx с формулой

Я пытаюсь прочитать файл xlsx после записи в существующий файл Excel xlsx с помощью openpyxl.

Мой файл Excel file1.xlsx со значением 1 на A1, значением 2 на A2 и значением A1 + A2 на A3, которое на данный момент равно 3.

def updateFile(a):
    wb = load_workbook('file1.xlsx')
    ws = wb.active
    #Update specific column
    ws['A1'] = a
    wb.save('file1.xlsx')

def readFile():
    wb = load_workbook('file1.xlsx')
    sheet = wb['Sheet1']
    print(sheet['A3'].value)

Моя программа собирается обновить A1 на file1.xlsx и прочитать данные на A3. Например, вызов updateFile(5) обновит A1 до 5 и, возможно, даст мне 7 на A3.

К сожалению, после вызова updateFile(5) readFile() выдаст = A1 + A2 в качестве вывода вместо 7.

Это в основном связано с тем, что данные в файле Excel обновляются, но не сохраняются. И если я хочу, чтобы readFile() выводил 7, мне нужно открыть file1.xlsx вручную, сохранить и закрыть.

Есть ли вообще или я неправильно использую чтение / запись в openpyxl для решения этих проблем? Я считаю, что я не сохранил файл должным образом или мне нужно найти способ открыть, сохранить, закрыть файл Excel программно.


person Takashiwa Max    schedule 08.10.2015    source источник


Ответы (3)


То, что вы видите, является ожидаемым поведением. Когда в ячейках есть формулы, Excel сохраняет результат формулы как кэшированное значение. openpyxl никогда не оценивает формулы, поэтому никогда не поддерживает кеш и не делает недействительным любой существующий кеш. Вместо этого, если вам нужны результаты формулы, вы можете загрузить файл с параметром data_only=True. Хотя это заменит формулу на значение.

Это описано в документации: http://openpyxl.readthedocs.org/en/stable/usage.html#read-an-existing-workbook

person Charlie Clark    schedule 08.10.2015
comment
Привет, Чарли, для информации, я пытался использовать data_only = True при обращении к предоставленной документации. Однако после вызова updateFile (5) A3 стал None, когда readFile () вызывается с wb = load_workbook ('file1.xlsx', data_only = True). Как сказано в сообщении, это можно исправить только после того, как я действительно открою файл Excel и сохраню его при закрытии. - person Takashiwa Max; 08.10.2015
comment
Это ожидаемое поведение: существующий кеш аннулируется openpyxl. Перед редактированием файла результат может быть кэширован как 7. После сохранения в openpyxl кеша не будет, поэтому открытие в режиме data_only будет возвращать None для каждого вычисления. Чтобы избежать этого, вы должны редактировать в режиме data_only, но при этом не теряются формулы. В противном случае пропустите файл через что-то вроде безголовой версии OpenOffice Calc, чтобы выполнить пересчет кеша. - person Charlie Clark; 08.10.2015
comment
Поэтому я предполагаю, что у меня нет возможности прочитать обновленную ячейку на A3 после записи данных с помощью updateFile (5). Поскольку редактирование в режиме «data_only» приведет к потере формул «A3» и, возможно, данные в «A3» также не будут обновлены. - person Takashiwa Max; 08.10.2015
comment
Если вы хотите отредактировать лист с формулами в нем и сохранить формулы, то результаты этих формул будут недоступны. Представьте, что у вас есть ячейка с формулой =A1+A2, и нет никакого способа узнать, правильно ли ранее кэшированное значение. Следовательно, он должен быть признан недействительным и пересчитан. Поскольку openpyxl не оценивает формулы, для этого потребуется другое приложение. - person Charlie Clark; 08.10.2015

У меня такая же проблема. Мой подход следующий:

print('Reopen all files and save again')
for eachFile in glob.glob(path + fileCriteria)[:]:
    xl = DispatchEx('Excel.Application')
    xl.Visible = False
    wb = xl.Workbooks.Open(eachFile)
    wb.Close(True)
person Sebastian    schedule 14.07.2016

Для тех, кто может столкнуться с этим, если вы не против установки openpyxl из исходного кода BitBucket, для этого есть исправление (бета!): https://bitbucket.org/cliffckerr/openpyxl/src/default/

person Cliff Kerr    schedule 30.01.2019