[英]Python openpyxl saving xlsm file gets error when opening
I have a script that opens an xlsm file and an xlsx file.我有一个脚本可以打开一个 xlsm 文件和一个 xlsx 文件。 It modifies the xlsm with data from the xlsx, then saves the xlsm file.
它使用来自 xlsx 的数据修改 xlsm,然后保存 xlsm 文件。 When i open that xlsm file after the script is run, I get an error shown in the image.
当我在脚本运行后打开该 xlsm 文件时,出现图像中显示的错误。
The file then works fine but I get an XML error shown below:该文件然后工作正常,但我收到如下所示的 XML 错误:
The code I am using is:我正在使用的代码是:
import openpyxl
destwb = openpyxl.load_workbook(filename="C:\\627 Data\\winphy\\071-000-022-00 627 data.xlsm", read_only=False, keep_vba=True)
.....Code.....
destwb.save(filename="C:\\627 Data\\winphy\\071-000-022-00 627 data2.xlsm")
I ran into something similar and pieced largely recycled code from this solution by Joost in this question: How to save XLSM file with Macro, using openpyxl我遇到了类似的事情,并通过拼凑很大程度上回收代码从该解决方案的Joost这样一个问题: 如何保存XLSM文件与宏,使用openpyxl
Apparently, openpyxl doesn't read or preserve all of the magic macro parts of an xslm when opening and saving.显然,openpyxl 在打开和保存时不会读取或保留 xslm 的所有魔术宏部分。 Since the files are in a zip format, the solution:
由于文件是 zip 格式,因此解决方案:
I took the sample code, turned it into a usable replacement for workbook.save(), fixed a missing file (likely Excel change since the original solution), added zip compression and creation of a backup file to the mix.我拿了示例代码,把它变成了 workbook.save() 的可用替代品,修复了一个丢失的文件(自原始解决方案以来可能是 Excel 更改),添加了 zip 压缩并创建了一个备份文件。 May this do what you need.
愿这做你需要的。
def saveXlsm(wb, xlsmname):
'''Some crazy workaround to fix what openpyxl cannot when recreating an xlsm file.
Use as replacement for workbook.save()
'''
import zipfile
from shutil import copyfile
from shutil import rmtree
# Unzip original and tmp into separate dirs
PAD = os.getcwd()
wb.save('tmp.xlsx')
with zipfile.ZipFile(xlsmname, 'r') as z:
z.extractall('./xlsm/')
with zipfile.ZipFile('tmp.xlsx', 'r') as z:
z.extractall('./xlsx/')
# copy pertinent left out macro parts into tmp
copyfile('./xlsm/[Content_Types].xml','./xlsx/[Content_Types].xml')
copyfile('./xlsm/xl/_rels/workbook.xml.rels','./xlsx/xl/_rels/workbook.xml.rels')
copyfile('./xlsm/xl/vbaProject.bin','./xlsx/xl/vbaProject.bin')
copyfile('./xlsm/xl/sharedStrings.xml','./xlsx/xl/sharedStrings.xml')
# create a new tmp zip to rebuild the xlsm
z = zipfile.ZipFile('tmp.zip', 'w', zipfile.ZIP_DEFLATED)
# put all the parts back into the new Frankenstein
os.chdir('./xlsx')
for root, dirs, files in os.walk('./'):
for file in files:
z.write(os.path.join(root, file))
z.close()
os.chdir(PAD)
# humanize Frankenstein
bakname = xlsmname + '.bak'
if os.access(bakname, os.W_OK):
os.remove(bakname)
os.rename(xlsmname, bakname)
os.rename('tmp.zip', xlsmname)
#clean
rmtree('./xlsm/')
rmtree('./xlsx/')
os.remove('./tmp.xlsx')
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.