2013-07-16 190 views
3

我有.xlsm文件有函數。我正在使用openpyxl加載它,並將一些數據寫入該文件,最後希望保存爲不同的.xlsm文件。如何用宏保存XLSM文件,使用openpyxl

將文件保存爲XLSM文件我在我的Python腳本中使用了下面的代碼。

wb.save('testsave.xlsm'); 

但是我不能打開該文件,如果我保存如上。但如果我將它保存爲.xlsx,那麼我可以在沒有原始文件所具有的宏功能的情況下打開文件。

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

回答

2

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

根據this thread

我想你不應該給XLSM擴展,因爲該文件將 不含VBA代碼。 openpyxl僅用於構建xlsX文件。

給一個嘗試this fork相反:如果你通過keep_vba=True參數load_workbook它應該做的工作。

希望有所幫助。

+1

它沒有爲我工作。這是我的代碼'wb = load_workbook('template.xlsm',keep_vba ​​= True);' – AnujAroshA

+0

如果這個分支不起作用 - 那麼,就沒有辦法使用'openpyxl'工作。 – alecxe

5

對於我這個工作,與一起版本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

+0

是否有可能從python調用並運行宏? – toasteez

+0

如果您安裝了MS Office並運行Windows,那麼您可以使用[OLE api](http://stackoverflow.com/a/2141981/4200284)運行它。 否則,你必須用Python中的openpyxl重新設計宏代碼。 – eule

+0

此鏈接不會涉及任何與'xlsm'相關的內容!事實上,如果你去http://openpyxl.readthedocs.io/en/latest/usage.html?highlight=xlsm你會看到,沒有什麼東西是最重要的,因爲沒有任何關於xlsm的內容。 –

3

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

1)打開原始文件(比如:1.xlsm)和做魔術openpyxl

2)保存爲2.xlsx

3)這兩個文件實際上是壓縮文件:提取到臨時dirs

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

該解決方案與我找到的最接近,但仍然存在一些文件錯誤,即Excel會嘗試恢復。在這個恢復過程中,它(有時並不總是)把宏搞亂! –

相關問題