サポートしているマクロを有効にした PowerPoint ファイルの "ビルド スクリプト" として機能する Python スクリプトを作成しました。
このスクリプトは、新しい空の PowerPoint プレゼンテーションを作成し、すべての VBA モジュールをインポートし、ファイルを保存して ZIP アーカイブに変換し、RibbonUI 構成 ( ribbon_xml.xmlファイルとmylogo.jpgファイル) を挿入します。
出力ファイルを使用しようとするまでは (.zip から .pptm に手動で名前を変更し、PowerPoint で開きます)。
エラーコードは正常に終了しますが、PPTM ファイルに変換されたときの出力アーカイブ (copy.zip) は正常に開きません。
構成に問題があるという警告が表示され、PowerPoint がファイルの修復を試みます。
もちろん、その性質上、問題が何であるかを示しているわけではありません。「読み取れないコンテンツ」が見つかり、そのようなコンテンツが「削除された」ということだけです...私が作成したいくつかのファイルを比較した後に確認できる唯一のこと手動で、CustomUI の XML 属性が id 属性の一部としてある種の GUID を使用しているように見えることです。
現在の回避策:関数build_ribbonは、CustomUI エディター ツールを使用して手動で行うことができ、PPTM 出力を確実に生成するには約 3 分かかります。
CustomUI XML / リボン XML インターフェイスの実装に関する質問であるため、これは特に「Python」に関する質問ではありません。
完全なコード:
import win32com.client
import os
import zipfile
import uuid
#### PARAMETERS
vba_source_control_path = r"C:\Repos\MyAddIn\VBA\ChartBuilder_PPT\Modules"
output_path = r"C:\debug\output.pptm"
ribbon_xml_path = r"C:\Repos\MyAddIn\Ribbon XML\ribbon_xml.xml"
ribbon_logo_path = r"C:\Repos\MyAddIn\Ribbon XML\mylogo.jpg"
def build_addin(pres, path):
"""
This procedure does the following:
1. adds all of the VBComponents to the working PPTM file
The .PPTM file is used for local development & debugging and
is only usually packaged as a PPAM for Testing and Distribution
"""
for fn in [fn for fn in os.listdir(path) if not(fn.endswith(".frx"))]:
pres.VBProject.VBComponents.Import(path + "\\" + fn)
# Clean up old files, if any
if os.path.isfile(output_path):
os.remove(output_path)
if os.path.isfile(output_path.replace(".pptm", ".zip")):
os.remove(output_path.replace(".pptm", ".zip"))
# Save the new file with VBProject components
pres.SaveAs(output_path)
pres.Close()
def build_ribbon_zip():
"""
build_ribbon_zip handles manipulation of the .ZIP contents and places the
necessary components within the PPTM ZIP archive structure
2. converts the PPTM to a .ZIP
3. Adds the CustomUI XML and logo.jpg to the .ZIP directory
4. converts the .ZIP to a PPTM
"""
id = '<Relationship Id='
schema = 'http://schemas.openxmlformats.org/officeDocument/2006/'
_path = output_path.replace(".pptm", ".zip")
copy_path = r"C:\debug\copy.zip"
# Convert to ZIP archive
os.rename(output_path, _path)
zip = zipfile.ZipFile(_path, 'a')
copy = zipfile.ZipFile(copy_path, 'w')
guid = str(uuid.uuid4()).replace('-', '')[:16]
for itm in [itm for itm in zip.infolist() if itm.filename != r'_rels/.rels']:
buffer = zip.read(itm.filename)
copy.writestr(itm, buffer)
# Append the Logo file to the .zip and create the archive
copy.write(ribbon_logo_path, r'\CustomUI\images\jdplogo.jpg')
# append the CustomUI xml part to the .zip and create the archive
copy.write(ribbon_xml_path, r'\CustomUI\customUI14.xml')
# append the .rels file to CustomUI\_rels
rels_xml = r'<?xml version="1.0" encoding="UTF-8" standalone="yes"?>'
rels_xml += r'<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">'
rels_xml += r'<Relationship Id="jdplogo" Type="'+schema+'relationships/image" Target="images/jdplogo.jpg"/>'
rels_xml += r'</Relationships>'
copy.writestr(r'CustomUI\_rels\customUI14.xml.rels', rels_xml.encode('utf-8'))
# get the existing _rels/.rels XML content and append the UI:
rels_xml = zip.read(r'_rels/.rels').rstrip()[:-16]
rels_xml += id + r'"R'+guid+'" Type="http://schemas.microsoft.com/office/2007/relationships/ui/extensibility"'
rels_xml += r'Target="customUI/customUI14.xml"/></Relationships>'
rels_xml = rels_xml.replace(os.linesep, '')
# this file-like object is read-only, and the writestr method will create another .rels file...
copy.writestr(r'_rels/.rels', rels_xml.encode('utf-8'))
zip.close()
copy.close()
if __name__ == "__main__":
"""
Procedure to create a new PowerPoint Presentation and insert the Code Modules from source control
"""
ppApp = win32com.client.Dispatch("PowerPoint.Application")
pres = ppApp.Presentations.Add(False)
pres.Slides.AddSlide(1, pres.SlideMaster.CustomLayouts(1))
build_addin(pres, vba_source_control_path)
ppApp.Quit()
build_ribbon_zip()