0

I've made a script in python which fills in certain cells in excel sheets which are fetched from a kivy interface. It should send an email with the data entered and make some filled in excel sheets. It works as it should, but the last part is printing the sheets automatically.. :D I've come across a script and it works to print automatical, the only problem is that I do not know how to make it print single sided instead of double sided.

I'm using openpyxl to adjust the data in the sheets and this library has some features that can change printer settings like margins, but I did not find anything about one sided printing. Also, I did not find how to print with openpyxl, that's why I'm using win32com.

import os, win32com.client

o = win32com.client.Dispatch('Excel.Application')
o.visible = True
wb = o.Workbooks.Open(path)
ws = wb.Worksheets([1 ,2 ,3])
ws.PrintOut()

Does anyone have an idea how to change the printer output to one sided pages?

Thank you for your time and attention.

yoonghm
  • 4,198
  • 1
  • 32
  • 48
Igor Markovic
  • 145
  • 1
  • 11
  • 1
    See this https://stackoverflow.com/questions/64243286/how-print-document-in-order-using-python. The point is to use `win32print` library to retrieve the selected printer's attribute and set the 'pDevMode' to `DMDUP_SIMPLEX` which is `0x0001`. – yoonghm Dec 07 '21 at 00:32
  • Perfect thank you very much. – Igor Markovic Dec 10 '21 at 14:12

1 Answers1

0

Thanks to @yoonghm and his link I've found how to make it work for me.

import win32api
import win32print
import win32com.client
from win32com.shell import shellcon, shell


o = win32com.client.Dispatch('Excel.Application')
o.visible = False
wb = o.Workbooks.Open(file_path)
printlist = [i+1 for i in sheetlist[:printamount]]
ws = wb.Worksheets(printlist)

#set to single sided
name = win32print.GetDefaultPrinter()
printdefaults = {"DesiredAccess": win32print.PRINTER_ALL_ACCESS}
handle = win32print.OpenPrinter(name, printdefaults)
level = 8
attributes = win32print.GetPrinter(handle, level)
attributes['pDevMode'].Duplex = 1
win32print.SetPrinter(handle, level, attributes, 0)
win32print.GetPrinter(handle, level)['pDevMode'].Duplex
##    shell.ShellExecuteEx(lpVerb='print', lpFile=file_path, lpParameters=name)
    
ws.PrintOut()
    
win32print.ClosePrinter(handle)
wb.Close()

attributes['pDevMode'].Duplex is used to print single sided, only problem was that in the link, by using level = 2: 'pDevMode' was not in attributes for my printer. For me it had to be level = 8.

I did not print using the commented out line as used by the link, because it did not print all four worksheets. Adjusting printlist to which worksheets you want and printing with ws.PrintOut() did that trick.

Igor Markovic
  • 145
  • 1
  • 11