scanny / python-pptx

Create Open XML PowerPoint documents in Python
MIT License
2.44k stars 528 forks source link

How to embed a zip file? #752

Open corinnaliw opened 3 years ago

corinnaliw commented 3 years ago

Hi , How to embed a zip file using python-pptx?

scanny commented 3 years ago

Can you do that with PowerPoint?

corinnaliw commented 3 years ago

Hi scanny, Yes,i can embed a zip file with PowerPoint

corinnaliw commented 3 years ago

Hi scanny, I embedded a zip file with PowerPoint,then inspected the XML,and found the following parameters: CONTENT_TYPE is "application/vnd.openxmlformats-officedocument.oleObject" RELATIONSHIP_TYPE is "http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject" partname_template is "/ppt/embeddings/oleObject%d.bin" progId is "Package"

I added this parameters into python-pptx,then ran the code,but can't embed a zip file successfully.What parameters did I miss?

scanny commented 3 years ago

Where did you find those? Package doesn't sound quite right as the progId. That should be a str like Excel.Sheet.12 with like application, object-type, version elements separated by periods. You find that in the progId attribute of the <p:oleObj> element.

There's an example on this page of the analysis documentation under the sub-heading "simple column chart" (a typo leftover from a prior page):
https://python-pptx.readthedocs.io/en/latest/dev/analysis/shp-ole-object.html#xml-specimens

Once you get that progId string you just pop it in here:
https://python-pptx.readthedocs.io/en/latest/api/shapes.html#pptx.shapes.shapetree.SlideShapes.add_ole_object

Show the code you tried if it still doesn't work and describe "how" it doesn't work, like it gives an error or just doesn't show up or whatever. Also mention what's inside the Zip file in general terms; note that a XLSX file is a zip archive, for example, but that gets a different progId.

corinnaliw commented 3 years ago

I embedded a xlsx file with PowerPoint,saved it as an XML file,and found the progId in the XML,progId is "Excel.Sheet.12":

<a:graphicData uri="http://schemas.openxmlformats.org/presentationml/2006/ole">
 <mc:AlternateContent xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006">
  <mc:Choice xmlns:v="urn:schemas-microsoft-com:vml" Requires="v">
   <p:oleObj spid="_x0000_s1027" name="工作表" showAsIcon="1" r:id="rId3" imgW="914400" imgH="792360" progId="Excel.Sheet.12">
    <p:embed/>
   </p:oleObj>
  </mc:Choice>
  <mc:Fallback>
   <p:oleObj name="工作表" showAsIcon="1" r:id="rId3" imgW="914400" imgH="792360" progId="Excel.Sheet.12">

and I embedded a zip file with PowerPoint,saved it as an XML file,and found the progId in the XML at the same location:

<a:graphicData uri="http://schemas.openxmlformats.org/presentationml/2006/ole">
 <mc:AlternateContent xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006">
  <mc:Choice xmlns:v="urn:schemas-microsoft-com:vml" Requires="v">
   <p:oleObj spid="_x0000_s1027" name="包装程序外壳对象" showAsIcon="1" r:id="rId3" imgW="914400" imgH="792360" progId="Package">
    <p:embed/>
   </p:oleObj>
  </mc:Choice>
  <mc:Fallback>
   <p:oleObj name="包装程序外壳对象" showAsIcon="1" r:id="rId3" imgW="914400" imgH="792360" progId="Package"> 

The progId is "Package".I don't know what I did wrong Packaged in ZIP is a docx file.

scanny commented 3 years ago

What's the code you used to do the embedding, like the shapes.add_ole_object() call.

corinnaliw commented 3 years ago

slide.shapes.add_ole_object(path, PROG_ID.XLSX, left=Inches(1), top=Inches(1)) I used this API to embed the xlsx file,and embed successfully. I dont know how to use this API to embed the zip file. In my recovery above, the embedding zip file I said was inserted directly using the Insert-> Object function in PowerPoint, not embedded with code.

scanny commented 3 years ago

Try slide.shapes.add_ole_object(path, "Package", left, top).

But if the zip file is a .docx file, why wouldn't you use PROG_ID.DOCX?

corinnaliw commented 3 years ago

slide.shapes.add_ole_object(path, "Package", left=Inches(1), top=Inches(1)) I used this API to embed a zip file,it can generate a .ppt file, open the .ppt file, double-click the inserted icon, nothing happens.

I packaged a docx file just to test whether I can insert a zip file, what we finally want to achieve is to insert a zip file, this zip file may contain multiple other files

corinnaliw commented 3 years ago

slide.shapes.add_ole_object(path, "Excel.Sheet.12", left=Inches(1), top=Inches(1)) I try to change PROG_ID.XLSX to "Excel.Sheet.12",it can generate a .ppt file, open the .ppt file, double-click the inserted icon, popup: Unable to find the server application, source file and project, or an unknown error returned. Please reinstall the service program. Maybe progid should not be placed here directly.

scanny commented 3 years ago

Compare the XML that works to the XML when you use "Package" in .add_ole_object(). If you can find the difference then you can possibly fix it.

Note that opening OLE objects is very machine dependent because it is essentially starting up an application on that machine when you double-click the icon. The ProgID bit identifies which application (program) to start up and feed the binary object to. So if you test on two different machines you can get very different results. Also note that in general, only embedded XLSX works on Mac (maybe .docx too, but not .pptx, .pdf, etc.).