I'm trying to use win32com to print an Excel sheet. This works fine if I have a remote desktop connection the VM this is running on, but if I'm disconnected, the task fails.
I've hit two related errors:
1) With the print area set in Excel:
- connected to VM: the file prints as expected
- not connected: the file prints but without the print area set, so spills onto multiple pages
2) Print area not set, but PageSetup set using Python
- connected to VM: the file prints as expected
- not connected: the file fails to print with a 1004 error "Unable to set the PaperSize property of the PageSetup class"
Other questions with this error suggest that the printer drivers are missing, but this isn't the case for me, since it prints fine when I'm connected to the VM via RDP.
Here's my wrapper class for Excel:
from pathlib import Path
import pythoncom
import win32com.client
from utils.excel.constants import XLQUALITY_STANDARD
from utils.excel.constants impor
class ExcelApp:
def __init__(self, is_visible=False):
pythoncom.CoInitialize()
excel = win32com.client.Dispatch("Excel.Application")
excel.Visible = is_visible
self.app = excel
def __getattr__(self, item):
return getattr(self.app, item)
def __enter__(self):
return self
def __exit__(self, exc_type, exc_value, exc_traceback):
self.app.Quit()
def open(self, path):
path = self._regularise_path(path)
return self.app.Workbooks.Open(path)
def _regularise_path(self, path):
path = str(Path(path).absolute())
if ":\\" not in path:
path = path.replace(":", ":\\")
return path
def close(self, wb, prompt=False):
wb.Close(prompt)
def save_as_pdf(
self,
wb,
sheets,
path,
quality=XLQUALITY_STANDARD,
include_doc_properties=False,
ignore_print_areas=False,
page_setup=None,
):
page_setup = page_setup or {}
path = self._regularise_path(path)
wb.WorkSheets(sheets).Select()
for prop, val in page_setup.items():
setattr(wb.ActiveSheet.PageSetup, prop, val)
wb.ActiveSheet.ExportAsFixedFormat(XLTYPE_PDF, path, quality, include_doc_properties, ignore_print_areas)
And the calling code:
page_setup = {"Zoom": False, "FitToPagesTall": 1, "FitToPagesWide": 1, "PaperSize": XLPAPER_TABLOID}
with ExcelApp() as excel:
wb = excel.open(src)
excel.save_as_pdf(wb, sheets, dst, page_setup=page_setup)