I am using an Epson TM-T20II thermal receipt printer, and I need to print receipt out with Danish characters (æ,ø,å). To ESCPOS code for character language selection is described here. My Python code is as below
import win32print
import six
#create some raw data
rawdata = b'\x1b\x40' #Instantiate the printer ESC @
rawdata = rawdata + b'\x1b\x52\x10' #Select the Danish II character set as in documentation ESC R
where n = 10
rawdata = bytes('Print æ,ø,å', 'utf-8') + b'\n' + b'\x1d\x56' + six.int2byte(66) + b'\x00' #print
some text and cut
#Creating the printing job in Windows 10 and send the raw text to the printer driver
printer = win32print.OpenPrinter('EPSON TM-T20II Receipt')
hJob = win32print.StartDocPrinter(printer, 1, ("Test print", None, "RAW"))
win32print.WritePrinter(printer, rawdata)
win32print.EndPagePrinter(printer)
win32print.ClosePrinter(printer)
My problem is that I get some strange character printed out. Also I have set the printer to Danish II by holding down the feed button and while power on the printer. What have I missed?
For the time being, what you might want to try is to change the encoding specification below from utf-8 to cp865.
rawdata = bytes('Print æ,ø,å', 'utf-8') + b'\n' + b'\x1d\x56' + six.int2byte(66) + b'\x00' #print
If that doesn't work, you should stop using win32print and switch to pyserial.
It is also necessary to switch the printer mode, uninstall the Advanced Printer Driver, and install the printer serial port driver.
Then the application program needs to create all the print data using the raw ESC/POS commands.
The reason is as follows.
You can get the Advanced Printer Driver of TM-T20II and manual & sample program here.
EPSON Advanced Printer Driver for TM-T20II
According to the sample program "Step 1 Printing Device Font", in order to send a raw ESC/POS command to the printer, it is necessary to select a specific device font.
Prints "Hello APD" with a device font and autocuts a receipt.
The core of the sample source in C ++ is as follows.
CDC dc; /* * Create the device context for the printer */ if(! dc.CreateDC(EPS_DRIVER_NAME, EPS_PRINTER_NAME, NULL, NULL) ) { AfxMessageBox(_T("Printer is not available.")); return; } dc.StartDoc(&di); /* * Perform the printing of the text */ CFont font, *old; font.CreatePointFont(95, "FontA11", &dc); old = dc.SelectObject(&font); dc.TextOut(20, 10, "Hello APD!"); dc.SelectObject(old); font.DeleteObject(); dc.EndPage(); dc.EndDoc(); dc.DeleteDC();
Here's what it looks like in VB.
Dim printFont As New Font("Lucida Console", 8, FontStyle.Regular, GraphicsUnit.Point) ' Substituted to FontA Font e.Graphics.PageUnit = GraphicsUnit.Point ' Print the string at 6,4 location using FontA font. e.Graphics.DrawString("Hello APD!", printFont, Brushes.Black, 6, 4) ' Indicate that no more data to print, and the Print Document can now send the print data to the spooler. e.HasMorePages = False
Isn't it very difficult or impossible to port these to Python's win32print?
The win32print API doesn't seem to have the ability to customize fonts in the middle of printing.
Module win32print
And StartDocPrinter and WritePrinter have the following explanation.
win32print.StartDocPrinter
Note that the printer driver might ignore the requested data type.
Suitable for copying raw Postscript or HPGL files to a printer.
The ESC/POS command is not raw PostScript or HPGL, and EPSON's Advanced Printer Driver does not necessarily send such data with a win32print call.