簡體   English   中英

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

[英]How to save XLSM file with Macro, using openpyxl

我有一個帶有功能的.xlsm文件。 我正在使用openpyxl加載它並將一些數據寫入文件,最后想保存為不同的.xlsm文件。

要將文件保存為 XLSM 文件,我在 Python 腳本中使用了以下代碼。

wb.save('testsave.xlsm');

但是如果我按上述方式保存,我將無法打開該文件。 但是如果我將它保存為.xlsx那么我可以在沒有原始文件的宏功能的情況下打開文件。

我想打開一個具有宏功能的 Excel 工作表,編輯文件並使用openpyxl將其保存為新的.xlsm文件。 我怎樣才能做到這一點?

對我來說,這與版本openpyxl==2.3.0-b2一起工作

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

它也在此處的文檔中提及: http ://openpyxl.readthedocs.org/en/latest/usage.html?highlight=keep_vba#write-a-workbook-from-xltm-as-xlsm

我不知道這對提出問題的人是否仍然相關,但我正在處理同樣的問題並找到了可能的解決方案。

  1. 打開原始文件(比如: 1.xlsm )並用 openpyxl 做魔術;
  2. 另存為2.xlsx
  3. 這兩個文件實際上都是壓縮文件:將它們解壓縮到一個臨時目錄;
  4. 將文件從原始文件的目錄復制到xlsx文件的目錄:其中一個文件是宏 ( vbaProject.bin ),其中 2 個文件是必需的,因為它們描述了文件的類型等;
  5. 將屬於xlsx目錄的所有文件放回一個 zip 文件,並將其從zip重命名為xlsm 此文件包含原始宏並已使用openpyxl進行編輯;
  6. 可選)刪除兩個臨時目錄和2.xlsx文件。

示例代碼:

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

我在使用 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')

沒錯,openpyxl無法讀寫VBA代碼。

根據這個線程

我認為您不應該提供 xlsM 擴展名,因為該文件將不包含 VBA 代碼。 openpyxl 僅用於構建 xlsX 文件。

試試這個 fork :如果你將keep_vba=True參數傳遞給load_workbook它應該可以完成這項工作。

希望有幫助。

如果您的初始 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)

最好使用 xlwings 來處理 xlsm 文檔。 我已經測試過了。

將 xlwings 導入為 xw

wb = xw.Book(DATA.xlsm)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM