python-3.xepsonposescpos

Epson ESCPOS print Danish character using ESC R n command


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?


Solution

  • 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.

    win32print.WritePrinter

    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.