如何使用openpyxl使用宏保存XLSM文件

时间:2013-07-16 11:50:03

标签: python openpyxl xlsm

我的 .xlsm 文件带有功能。我正在使用 openpyxl 加载它并将一些数据写入文件,最后想要另存为 .xlsm 文件。

要将文件保存为XLSM文件,我在Python脚本中使用了以下代码。

wb.save('testsave.xlsm');

但如果我如上所述保存,我就无法打开该文件。但如果我将其保存为 .xlsx ,那么我可以在没有原始文件的宏功能的情况下打开文件。

我想打开一个具有宏功能的Excel工作表,编辑该文件并使用 openpyxl 将其另存为新的 .xlsm 文件。我怎么能这样做?

6 个答案:

答案 0 :(得分:11)

对我而言,这与版本openpyxl==2.3.0-b2

一起使用
wb = load_workbook(filename='original.xlsm', read_only=False, keep_vba=True)
..
wb.save('outfile.xlsm')

这里的文档也是mentioend:http://openpyxl.readthedocs.org/en/latest/usage.html?highlight=keep_vba#write-a-workbook-from-xltm-as-xlsm

答案 1 :(得分:5)

我不知道这是否仍然与提出问题的人有关,但我正在处理同样的问题,并找到了可能的解决方案。

  1. 打开原始文件(例如:1.xlsm)并使用openpyxl执行魔术;
  2. 另存为2.xlsx;
  3. 这两个文件实际上都是压缩文件:将它们解压缩到一个临时目录;
  4. 将文件从原始文件的目录复制到xlsx文件的目录:其中一个文件是宏(vbaProject.bin),其中2个文件是必需的,因为它们描述了类型该文件以及其他内容;
  5. 将属于xlsx目录的所有文件放回zip文件中,并将其从zip重命名为xlsm。此文件包含原始宏,并已使用openpyxl;
  6. 进行了编辑
  7. 可选)删除两个临时目录和2.xlsx文件。
  8. 示例代码:

    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')
    

答案 2 :(得分:2)

没错,openpyxl无法读写VBA代码。

根据this thread

  

我认为你不应该给xlsM扩展名,因为文件会   不包含VBA代码。 openpyxl仅用于构建xlsX文件。

尝试改为this fork:如果您将keep_vba=True参数传递给load_workbook,它应该可以胜任。

希望有所帮助。

答案 3 :(得分:0)

使用openpyxl编辑xlsm文件时,我遇到了同样的问题。我尝试了stackoverflow和其他论坛中提供的大多数解决方案/解决方法。但是他们都不起作用。然后我发现xlwings,这个python库处理xlsm文档,它保留了所有宏。

import xlwings as xw
wb = xw.Book('macro_xl.xlsm')
sheet = wb.sheets['Sheet1']
sheet.range('A1').value = 'From Script'
wb.save('result_file_name.xlsm')

答案 4 :(得分:0)

如果您最初的excel是使用python创建的,则可能还需要添加workbook.xml并解析xlms表:

for sheet in range(1,4):
    with open('sheetX.xml', 'r') as myfile: 'r') as myfile:
        my_str=myfile.read()

substr = "<dimension ref="
inserttxt = "<sheetPr codeName=\"Sheet"+str(sheet)+"\"/>"

idx = my_str.index(substr)
my_str = my_str[:idx] + inserttxt + my_str[idx:]

with open('sheetX.xml', "w") as text_file:
    text_file.write(my_str)

答案 5 :(得分:0)

最好使用xlwings处理xlsm文档。我已经测试过了。

将xlwings导入为xw

wb = xw.Book(DATA.xlsm)