Проблемы с любой из ошибок ; writer.book=book
AttributeError: can't set attribute 'book'
или BadZipFile
для кода, не выдающего ошибку badzipfile, я помещаю строку кода, которая сначала записывает файл excel, dataOutput=pd.DataFrame(dictDataOutput,index=[0])
но, хотя я не могу избавиться от writer.book = book AttributeError: can't set attribute 'book'
Как подсказывает один из ответов SO, мне нужно вернуть openpyxl к предыдущим версиям или работать с файлом CSV, а не с excel. Я думаю, что это не решение. Должно быть решение, которое я не мог получить
dataOutput=pd.DataFrame(dictDataOutput,index=[0])
dataOutput.to_excel('output.xlsx') 'output.xlsm'
book = load_workbook('output.xlsx') 'output.xlsm'
writer = pd.ExcelWriter('output.xlsx')OR'output.xlsm'#,engine='openpyxl',mode='a',if_sheet_exists='overlay')
writer.book = book
writer.sheets = {ws.title: ws for ws in book.worksheets}
for sheetname in writer.sheets:
dataOutput.to_excel(writer,sheet_name=sheetname, startrow=writer.sheets[sheetname].max_row, index = False,header= False)
writer.save()
Я искал ответ в введите описание ссылки здесь и в подробном решении атрибутаError в введите описание ссылки здесь
--- я пробовал по-другому
with pd.ExcelWriter('output.xlsx', mode='a',if_sheet_exists='overlay') as writer:
dataOutput.to_excel(writer, sheet_name='Sheet1')
writer.save()
Но на этот раз выдал другую ошибку
FutureWarning: save is not part of the public API, usage can give in unexpected results and will be removed in a future version
писатель.сохранить()
после комментариев @Andrew я изменил свой код таким образом;
with pd.ExcelWriter('outputData.xlsm', engine='openpyxl', mode='a', if_sheet_exists='overlay') as writer:
book = load_workbook('outputData.xlsm', keep_vba=True)
writer.book = book
writer.sheets = {ws.title: ws for ws in book.worksheets}
current_sheet = book['Sheet1']
Column_A = current_sheet['A']
maxrow = max(c.row for c in Column_A if c.value is not None)
for sheetname in writer.sheets:
AllDataOutput.to_excel(writer, sheet_name=sheetname, startrow=maxrow, index=False, header=False)
Есть несколько вещей, которые неясны в вашем вопросе, но я сделаю все возможное, чтобы попытаться ответить на то, что, как я думаю, вы пытаетесь сделать.
Во-первых, то, что не будет работать:
dataOutput.to_excel('output.xslx')
вы создаете книгу Excel только с одним простынь. Позже кажется, что вы пытаетесь написать несколько листов, но вы сможете написать только один лист, так как это все, что есть в рабочей книге с самого начала..save()
считается устаревшим, и вместо него следует использовать .close()
. Но рекомендуется использовать контекстный менеджер (with ... as ... :
), чтобы вам не приходилось этого делать.ExcelWriter
использует режим w
(запись), поэтому ошибка BadZipFile
, с которой вы сталкивались ранее, скорее всего, была связана с порядком запуска вещей. Если бы вы написали книгу с помощью to_excel
, затем загрузили ее с помощью openpyxl
, затем использовали ExcelWriter
, вы бы написали, загрузили и сразу перезаписали файл пустым. Если вы затем попытаетесь снова загрузить книгу, не воссоздав ее с помощью to_excel
, вы попытаетесь загрузить пустой файл, поэтому возникает эта ошибка.Ответы, на которые вы ссылались в своем вопросе, похоже, используют гораздо более старую версию pandas
с совершенно другим поведением, связанным с взаимодействием с файлами Excel. Последние версии, кажется, немного упрощают вещи!
В качестве примера решения я предполагаю, что у вас есть два DataFrames
с именами df1
и df2
, которые вы хотите записать в Sheet_1
и Sheet_2
в output.xlsx
, и вы хотите обновить данные на этих листах (используя опцию overlay
) с дополнительными DataFrames
, называемыми df3
и df4
. Для подтверждения у меня установлены openpyxl = 3.0.10
и pandas = 1.5.0
.
Поскольку у вас есть вещи, написанные в настоящее время, в dataOutput
нет никаких обновлений, которые были бы отражены в output.xslx
, но я собираюсь создать словарь под названием df_dict
, который может содержать DataFrames
и обновляться на основе листов, в которые они должны быть записаны. . Я уверен, что вы можете приспособиться к своим потребностям, используя любую структуру данных, которую вы предпочитаете!
df1 = pd.DataFrame(data = {'A': ['a', 'b', 'c'], 'B': ['g','h','i']})
df2 = pd.DataFrame(data = {'C': ['o', 'p', 'q'], 'D': ['u','v','w']})
df_dict = {'Sheet_1': df1, 'Sheet_2': df2}
with pd.ExcelWriter('output.xlsx') as writer:
for sheetname, dfname in df_dict.items():
dfname.to_excel(writer, sheet_name = sheetname)
# Updated data is put in DataFrames
df3 = pd.DataFrame(data = {'A': ['a', 'b', 'c', 'd', 'e', 'f'], 'B': ['g', 'h', 'i', 'j', 'k', 'l']})
df4 = pd.DataFrame(data = {'C': ['o', 'p', 'q', 'r', 's', 't'], 'D': ['u', 'v', 'w', 'x', 'y', 'z']})
# df_dict is updated with the new DataFrames
df_dict = {`Sheet_1`: df3, 'Sheet_2': df4}
# This block now uses the name of the sheet from the workbook itself to get the updated data.
# You could also just run the same block as above and it would work.
with pd.ExcelWriter('output.xlsx', mode = 'a', if_sheet_exists = 'overlay') as writer:
for sheet in writer.sheets:
df_dict[sheet].to_excel(writer, sheet_name = sheet)
после закрытия () мой файл excel, кажется, деактивирует код макроса. Я не могу запустить его после запуска скрипта
Вы уверены, что «Из документов ExcelWriter .save() устарело, и вместо этого следует использовать .close()». он портит файл xlsm
Это то, что написано в документах, поэтому я предполагаю, что это так. Хотя, возможно, он все еще работает. Если вы настроите все так, как я сделал в своем ответе, вам не нужно сохранять или закрывать, поскольку файл сделает это автоматически при выходе из контекстного менеджера. Вы все еще пытаетесь сделать это по-другому?
Снова из документации ExcelWriter
вы можете передавать аргументы движку через аргумент engine_kwargs
. ExcelWriter
использует метод openpyxl.reader.excel.load_workbook
, когда openpyxl
используется движок. Из этих документов, keep_vba
является аргументом, поэтому добавьте engine_kwargs = {keep_vba: True}
(и убедитесь, что у вас есть engine = 'openpyxl'
) к вашим аргументам pd.ExcelWriter()
(для любого случая, когда вы используете ExcelWriter
), и это должно работать.
У меня есть только один лист с именем «Лист1», и я пытаюсь добавить к нему данные. Позже я принесу версию pandas 1.5.0, попробую ваш код и дам вам знать. О закрытии () я не знал, может быть, это говорит о том, что «файл excel поврежден» иногда, когда кнопка vba в файле перемещается. Я постараюсь и дам вам знать. Спасибо, если вам нужно отредактировать свой код на основе моего комментария, вы можете это сделать, потому что позже я буду читать его много раз, чтобы попасть в