1

Goal: using python, I want to open a Powerpoint presentation and print it using the "Microsoft Print to PDF" printer. I do NOT want to export it as PDF, I want to print it using Print to PDF. This is not a duplicate of this question.

Why: I have found that in my use case that Print to PDF gives better image quality, whereas Export as PDF is overly compressing the content. Also I do not have Acrobat Pro, so I have no way other than the Office default to export files to PDF. (For those curious, I have a large .pptx (12Mb, due to some high quality images). Export to PDF generates a PDF that's 1.4Mb large, Print to PDF generates another that's 1.8Mb. The image quality difference is such that one is ok, the other one is not).

What I have done: I've figured out how to Export as PDF with help from this question (but using win32com instead of comtypes).

I then tried to change things around so that I'd print instead of save, something like this:

powerpoint = win32com.client.Dispatch("Powerpoint.Application")
deck = powerpoint.Presentations.Open("prs.pptx")
deck.PrintOut()
deck.Close()
powerpoint.Quit()

This almost works, as it's choosing Microsoft Print to PDF as the printer (since it's the default). However, Print to PDF opens a prompt for the file name - and this is where I'm currently stuck. I want to find a way to programmatically deal with the file-dialog-like window and confirm the printing.

I checked whether I wanted deck.PrintOut(PrintToFile="prs.pdf"), however this didn't create any file.

Question:

1 - Is there a way, using win32com or similar, to invoke the deck.PrintOut() in a way that it will deal with the extra dialog? 2 - Alternatively, is there a way I can capture the dialog and deal with it?

I'm not too familiar with win32com and the documentation seems non-existent, so I wasn't sure what else to try.

Hope this question is sufficiently clear. Many thanks.

ddsLeonardo
  • 63
  • 1
  • 8
  • win32com is part of the pywin32 module. There is a mailing list for help, and there is http://timgolden.me.uk/pywin32-docs/html/com/win32com/HTML/docindex.html . Note, however, that win32com is just a way to access COM servers. To answer your question, you need to look into PowerPoint's object model to see if they have a way to specify a file name. – Tim Roberts Mar 03 '21 at 19:31
  • I would also point out that the "Export to PDF" task in Office has two options: "standard", intended for publishing, and "minimum size" for online only. You may be setting the wrong one. – Tim Roberts Mar 03 '21 at 19:33
  • Generally for win32com (at least the Office parts) I look at the VBA & C# documentation and try to translate. It looks like there is a background option. Try something like `deck.PrintOut(Background=True)`. See https://learn.microsoft.com/en-us/office/vba/api/powerpoint.printoptions.printinbackground and https://learn.microsoft.com/en-us/dotnet/api/microsoft.office.interop.word.options.printbackground?view=word-pia. Also this one from 9 years ago! https://stackoverflow.com/questions/7993387/python-printing-from-python32 – Alan Mar 03 '21 at 19:50
  • Hi @TimRoberts, I've played around with the export settings - and I am confident I've got everything set up to maximum quality, including the PowerPoint settings about compressing images. I do not have the links at hand now but there are others mentioning that the Office-default Export to PDF can be aggressive on compression, especially when dealing with .png files (my case). – ddsLeonardo Mar 04 '21 at 22:10

1 Answers1

0

I found the solution to my own problem above, so I will post as an answer.

It turns out that the attempt to use PrintOut was correct (doc here)! However I believe this method behaves asynchronously, so in the snippet below:

powerpoint = win32com.client.Dispatch("Powerpoint.Application")
deck = powerpoint.Presentations.Open("prs.pptx")
deck.PrintOut(PrintToFile="prs.pdf")
deck.Close()
powerpoint.Quit()

the print task is aborted by closing the presentation/quitting PowerPoint.

As silly as it sounds, the working code is:

powerpoint = win32com.client.Dispatch("Powerpoint.Application")
deck = powerpoint.Presentations.Open("prs.pptx")
deck.PrintOut(PrintToFile="prs.pdf")
time.sleep(10)  # Enough time to ensure the print operation is complete
deck.Close()
powerpoint.Quit()

I will work on something a little more elegant than a fixed sleep, probably a watch on the destination folder, but this resolved my problem. I hope anyone else finds this useful in the future.

ddsLeonardo
  • 63
  • 1
  • 8