C4D Python openpyxl не может сохранить.xlsm, но вызывает TypeError в zipfile.py
Это мой первый пост, и я усердно искал ответ, поэтому, пожалуйста, потерпите меня!
В конечном итоге я хочу иметь возможность изменить существующий файл.xslm, чтобы заполнить его данными о движении, которые я извлек в Cinema-4D через python.
Я попробовал keep_vba=True
как предложено здесь, но все равно получил ошибку, описанную ниже. Моя рабочая книга с макросами взята из Excel 2013, с работающим макросом, который я тоже написал. Мой рабочий код:
import os
from openpyxl import load_workbook
homeDir = os.path.expanduser('~')
openName = 'Timing_CHART.xlsm'
openPath = os.path.dirname(__file__) + "\\" + openName
saveName = raw_input('Please enter a save name: ')
savePath = homeDir+'\\Desktop\\'+saveName+'.xlsm'
wb = load_workbook(openPath, keep_vba = True)
ws = wb.active
ws['B10'].value = 'Loader' #Just as a test
ws['D10'].value = 25
wb.save(savePath)
Когда я запускаю этот код в среде Enthought Canopy (Python 2.7.6, 64-битная версия), он работает, как я и ожидал, - фантастика. Когда я пытаюсь запустить этот же код в той же версии Python, которая используется в моей установке Cinema-4D (Python 2.6.4 64-bit), он прекрасно работает до wb.save()
команда. Тогда я получаю целую кучу ошибок:
Traceback (most recent call last):
File "<pyshell#14>", line 1, in <module>
wb.save(savePath)
File "C:\Python26\lib\site-packages\openpyxl-2.3.2-py2.6.egg\openpyxl\workbook\workbook.py", line 263, in save
save_workbook(self, filename)
File "C:\Python26\lib\site-packages\openpyxl-2.3.2-py2.6.egg\openpyxl\writer\excel.py", line 239, in save_workbook
writer.save(filename, as_template=as_template)
File "C:\Python26\lib\site-packages\openpyxl-2.3.2-py2.6.egg\openpyxl\writer\excel.py", line 222, in save
self.write_data(archive, as_template=as_template)
File "C:\Python26\lib\site-packages\openpyxl-2.3.2-py2.6.egg\openpyxl\writer\excel.py", line 68, in write_data
archive.writestr(ARC_ROOT_RELS, write_root_rels(self.workbook))
File "C:\Python26\lib\site-packages\openpyxl-2.3.2-py2.6.egg\openpyxl\writer\workbook.py", line 88, in write_root_rels
arc = fromstring(workbook.vba_archive.read(ARC_ROOT_RELS))
File "C:\Python26\lib\zipfile.py", line 831, in read
return self.open(name, "r", pwd).read()
File "C:\Python26\lib\zipfile.py", line 594, in read
bytes = self.fileobj.read(bytesToRead)
TypeError: integer argument expected, got 'long'
Только когда я писал этот пост (и проверял свои высказывания, чтобы убедиться в том, что я говорю, верно), я обнаружил разницу между тем, что он работает / не работает с python v2.7.6 в Enthought Canopy. против Python v2.6.4 в Windows и Cinema-4D.
Первоначально я думал, что это специфично для C4D, но поскольку C4D также работает на Python 2.6.4, я надеюсь, что это можно просто сузить до решаемой проблемы с версией Python... или узнать наверняка, что это невозможно с питоном 2.6.4.
Любая помощь / совет очень ценится!
1 ответ
Ладно, не понимал, что разница в версии Python окажет влияние... но немного больше копания в этой области показали, что openpyxl перестал поддерживать Python 2.5 после версии 1.7. Я предполагаю, что нечто подобное произошло с python 2.6 между openpyxl 1.8 и текущим 2.4.
Я установил openpyxl v1.8.6 в расположение библиотеки C4D python 2.6.4 (вместе с setuptools-0.9.6-py2.6, потому что ему не понравился openpyxl-1.8.6-py2.6.egg в противном случае) и изменил одна строка моего кода в C4D. С этим обновлением мой код работал в C4D python v2.6.4, установленном как прелесть!
import os
from openpyxl import load_workbook
homeDir = os.path.expanduser('~')
openName = 'Timing_CHART.xlsm'
openPath = os.path.dirname(__file__) + "\\" + openName
saveName = raw_input('Please enter a save name: ')
savePath = homeDir+'\\Desktop\\'+saveName+'.xlsm'
wb = load_workbook(openPath, keep_vba = True)
ws = wb.active
ws['B10'].value = 'Loader' #Just as a test
ws['D10'].value = 25
wb.save(savePath)
При записи значений в ячейки нового файла.xlsm с openpyxl v.2.4 у меня изначально была строка:
ws.cell(column = curCol, row = curRow, value = eachKey)
Который должен был быть изменен на:
ws.cell(column = curCol, row = curRow).value = eachKey
Я надеюсь, что может помочь кому-то в будущем!