Pandas, добавляющий файл excel (xlsx), дает attribute.error

Проблемы с любой из ошибок ; writer.book=bookAttributeError: 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)
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
0
2 390
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Есть несколько вещей, которые неясны в вашем вопросе, но я сделаю все возможное, чтобы попытаться ответить на то, что, как я думаю, вы пытаетесь сделать.

Во-первых, то, что не будет работать:

  1. Из документации to_excel «Если вы хотите писать более чем на один лист в книге, необходимо указать объект ExcelWriter», поэтому при запуске dataOutput.to_excel('output.xslx') вы создаете книгу Excel только с одним простынь. Позже кажется, что вы пытаетесь написать несколько листов, но вы сможете написать только один лист, так как это все, что есть в рабочей книге с самого начала.
  2. Из документации ExcelWriter.save() считается устаревшим, и вместо него следует использовать .close(). Но рекомендуется использовать контекстный менеджер (with ... as ... :), чтобы вам не приходилось этого делать.
  3. По умолчанию 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)

У меня есть только один лист с именем «Лист1», и я пытаюсь добавить к нему данные. Позже я принесу версию pandas 1.5.0, попробую ваш код и дам вам знать. О закрытии () я не знал, может быть, это говорит о том, что «файл excel поврежден» иногда, когда кнопка vba в файле перемещается. Я постараюсь и дам вам знать. Спасибо, если вам нужно отредактировать свой код на основе моего комментария, вы можете это сделать, потому что позже я буду читать его много раз, чтобы попасть в

xlmaster 19.10.2022 07:46

после закрытия () мой файл excel, кажется, деактивирует код макроса. Я не могу запустить его после запуска скрипта

xlmaster 19.10.2022 08:42

Вы уверены, что «Из документов ExcelWriter .save() устарело, и вместо этого следует использовать .close()». он портит файл xlsm

xlmaster 19.10.2022 21:43

Это то, что написано в документах, поэтому я предполагаю, что это так. Хотя, возможно, он все еще работает. Если вы настроите все так, как я сделал в своем ответе, вам не нужно сохранять или закрывать, поскольку файл сделает это автоматически при выходе из контекстного менеджера. Вы все еще пытаетесь сделать это по-другому?

Andrew 20.10.2022 00:42

Снова из документации ExcelWriter вы можете передавать аргументы движку через аргумент engine_kwargs. ExcelWriter использует метод openpyxl.reader.excel.load_workbook, когда openpyxl используется движок. Из этих документов, keep_vba является аргументом, поэтому добавьте engine_kwargs = {keep_vba: True} (и убедитесь, что у вас есть engine = 'openpyxl') к вашим аргументам pd.ExcelWriter() (для любого случая, когда вы используете ExcelWriter), и это должно работать.

Andrew 20.10.2022 00:50

Другие вопросы по теме