web-dev-qa-db-ja.com

openpyxlを使用してマクロでXLSMファイルを保存する方法

。xlsmファイルにMacro関数が含まれています。 openpyxlを使用してロードし、データをファイルに書き込んで、最後に別の。xlsmファイルとして保存します。

ファイルをXLSMファイルとして保存するには、以下のコードをPythonスクリプトで使用しました。

wb.save('testsave.xlsm');

しかし、上記の方法で保存した場合、そのファイルを開くことができません。しかし、それを。xlsxとして保存すると、元のファイルにあったマクロ関数がなくてもファイルを開くことができます。

マクロ機能を持つExcelシートを開き、ファイルを編集して、新しい。xlsmファイルとして保存しますopenpyxlを使用します。どうやってやるの?

13
AnujAroshA

私にとって、これはバージョン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 =

17
eule

これが質問をした人にまだ関係があるかどうかはわかりませんが、私は同じ問題を扱っており、可能な解決策を見つけました。

  1. 元のファイル(例:1.xlsm)を開き、openpyxlで魔法をかけてください。
  2. 2.xlsxとして保存;
  3. どちらのファイルも実際には圧縮されたファイルです。一時ディレクトリに抽出します。
  4. 元のファイルのディレクトリからxlsxファイルのディレクトリにファイルをコピーします。ファイルの1つはマクロ(vbaProject.bin)であり、2つのファイルは、とりわけファイル;
  5. xlsxディレクトリに属する​​すべてのファイルをZipファイルに戻し、これをZipからxlsmに名前変更します。このファイルには元のマクロが含まれており、openpyxlで編集されています。
  6. オプション)2つの一時ディレクトリと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')
6
Joost

そうです、openpyxlはVBAコードを読み書きできません。

this thread によると:

ファイルにはVBAコードが含まれていないため、xlsM拡張子を付けないでください。 openpyxlは、xlsXファイルのビルドにのみ使用されます。

代わりに this fork を試してみてください:keep_vba=Trueパラメータをload_workbookに渡すと、それでうまくいきます。

お役に立てば幸いです。

2
alecxe

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')
0
John Prawyn

最初の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)
0
Michel Kluger