Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't Python set the Excel print area on a VM without open RDP connection?

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)
like image 710
Jamie Bull Avatar asked Dec 06 '25 05:12

Jamie Bull


1 Answers

Possible source of the issue

This problem occurs when there isn't a default printer selected on your computer. Excel cannot set or get page setup properties.

source

Possible solution

So, Make sure that the script is running with an account that:

  1. Has at least one printer set up.
  2. Has a default printer set up - this is a must!

Related:

  • Unable to set the PaperSize property of the PageSetup class
  • https://stackoverflow.com/a/23503999/426315
  • https://stackoverflow.com/a/57613740/426315
like image 191
itsho Avatar answered Dec 08 '25 18:12

itsho



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!