<p>我不知道这是否仍然是相关的人提出的问题,但我正在处理同样的问题,并找到了一个可能的解决方案。</p>
<ol>
<li>打开原始文件(比如:<code>1.xlsm</code>)并使用openpyxl执行魔术</li>
<li>另存为<code>2.xlsx</code></li>
<li>两个文件实际上都是压缩文件:将它们解压缩到一个临时目录</li>
<li>将文件从原始文件的目录复制到<code>xlsx</code>文件的目录:其中一个文件是宏(<code>vbaProject.bin</code>),其中两个文件是必需的,因为它们描述了文件的类型等</li>
<li>将属于<code>xlsx</code>目录的所有文件放回zip文件中,并将其从<code>zip</code>重命名为<code>xlsm</code>。此文件包含原始宏,并已使用<code>openpyxl</code>进行编辑</li>
<li>(<em>可选</em>)删除两个临时目录和<code>2.xlsx</code>文件。</li>
</ol>
<p>示例代码:</p>
<pre><code>import openpyxl
import zipfile
from shutil import copyfile
from shutil import rmtree
import os
PAD = os.getcwd()
wb = openpyxl.load_workbook('1.xlsm')
#####
# do magic with openpyxl here and save
ws = wb.worksheets[0]
ws.cell(row=2, column=3).value = 'Edited' # example
#####
wb.save('2.xlsx')
with zipfile.ZipFile('1.xlsm', 'r') as z:
z.extractall('./xlsm/')
with zipfile.ZipFile('2.xlsx', 'r') as z:
z.extractall('./xlsx/')
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')
z = zipfile.ZipFile('2.zip', 'w')
os.chdir('./xlsx')
for root, dirs, files in os.walk('./'):
for file in files:
z.write(os.path.join(root, file))
z.close()
#clean
os.chdir(PAD)
rmtree('./xlsm/')
rmtree('./xlsx/')
os.remove('./2.xlsx')
os.rename('2.zip', '2.xlsm')
</code></pre>