0

I am trying to use a Python program to read a series of non-western (Japanese/Chinese) Unicode character strings from an Excel .xls file and create an image file for each string. The xlrd module gives me the Unicode strings from the Excel file, where they are properly displayed.

An answer to a previous question provided some of the basic elements to use the Windows API in Python to render normal western text into an image file. However, if I change to the basic call to render 2 Japanese characters from a Unicode text string as:

f = Win32Font("MS Gothic", 24)
im = f.renderText(u'\u30bb\u30c3')
im.save("hope.png")

The code fails: UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)

Any help in using the Windows API to properly render the Unicode strings would be greatly appreciated.

4

3 回答 3

0

我花了几十个小时寻找一个 unicode ...W win32... 函数,直到 Mark Tolonen 给出答案,我立即将其实现为一个工作示例,其代码如下。如果一切顺利,您的打印机应该会输出一个字符串“汉字、にほんご、עברית、عربي我都市刷出。”。

# -*- coding: utf-8 -*-

import win32ui, win32con, win32gui, win32print, traceback

# init, bla bla bla
printername = win32print.GetDefaultPrinter()
hprinter = win32print.OpenPrinter(printername)
# load default settings
devmode = win32print.GetPrinter(hprinter, 8)["pDevMode"]
# this is where it gets INTERESTING:
# after the following two lines, use:
# dc for win32ui calls like LineTo, SelectObject, ...
# hdc for DrawTextW, your *MAGIC* function that supports unicode output
hdc = win32gui.CreateDC("WINSPOOL", printername, devmode)
dc = win32ui.CreateDCFromHandle(hdc)

# 1440 twips = 1 inch
dc.SetMapMode(win32con.MM_TWIPS)
# 20 twips = 1 pt
scale_factor = 20

# start the document, description as unicode
description = u'Test1'
dc.StartDoc(description)

# when working with the printer, enclose any potentially failing calls within a try block,
# because if you do not properly end the print job (see bottom), after a couple of such failures,
# you might need to restart windows as it runs out of handles or something and starts
# behaving in an unpredictable way, some documents fail to print, you cannot open windows, etc.

try :

    # Use a font
    font = win32ui.CreateFont({
        "name": "Arial Unicode MS", # a font name
        "height": int(scale_factor * 10), # 10 pt
        "weight": 400, # 400 = normal
    })

    # use dc -- SelectObject is a win32ui call
    dc.SelectObject(font)

    # this is the miracle where the unicode text gets to be printed; notice hdc,
    # not dc, for DrawTextW uses a different handle, i have found this in other posts
    win32gui.DrawTextW (hdc, u"\u6C49\u5B57\u3001\u306B\u307B\u3093\u3054\u3001\u05E2\u05D1\u05E8\u05D9\u05EA\u3001\u0639\u0631\u0628\u064A\u6211\u90FD\u4F1A\u5237\u51FA\u3002", -1, (0, -2000, 4000, -4000), win32con.DT_CENTER)

except :
    traceback.print_exc()

# must not forget to tell Windows we're done. This line must get called if StartDoc 
# was called, if you fail to do so, your sys might start behaving unexpectedly
dc.EndDoc()
于 2013-04-20T19:30:56.827 回答
0

您需要使用 Unicode 版本的 Win32Api。快速浏览另一个问题的链接,您至少需要win32gui.DrawTextW而不是win32ui.DrawTextWin32Font实现中。注意 win32 g ui 是本机 API,而不是win32ui包装的 MFC API。在我快速浏览的文档中,我没有看到使用 Unicode 版本的 MFC 调用的方法pywin32,因此您需要从PyCDCusing中获取本机句柄GetSafeHdc才能将其与本机 API 一起使用。

如果您需要更多帮助,请发布一个完整的示例。

于 2012-06-28T03:21:04.993 回答
0
# -*- coding: utf-8 -*-

import win32ui, win32con, win32gui, win32print, traceback

# init, bla bla bla
printername = win32print.GetDefaultPrinter()
hprinter = win32print.OpenPrinter(printername)
# load default settings
devmode = win32print.GetPrinter(hprinter, 8)["pDevMode"]
# this is where it gets INTERESTING:
# after the following two lines, use:
# dc for win32ui calls like LineTo, SelectObject, ...
# hdc for DrawTextW, your *MAGIC* function that supports unicode output
hdc = win32gui.CreateDC("WINSPOOL", printername, devmode)
dc = win32ui.CreateDCFromHandle(hdc)

# 1440 twips = 1 inch
dc.SetMapMode(win32con.MM_TWIPS)
# 20 twips = 1 pt
scale_factor = 20

# start the document, description as unicode
description = u'Test1'
dc.StartDoc(description)

# when working with the printer, enclose any potentially failing calls within a try block,
# because if you do not properly end the print job (see bottom), after a couple of such failures,
# you might need to restart windows as it runs out of handles or something and starts
# behaving in an unpredictable way, some documents fail to print, you cannot open windows, etc.

try :

    # Use a font
    font = win32ui.CreateFont({
        "name": "Arial Unicode MS", # a font name
        "height": int(scale_factor * 10), # 10 pt
        "weight": 400, # 400 = normal
    })

    # use dc -- SelectObject is a win32ui call
    dc.SelectObject(font)

    # this is the miracle where the unicode text gets to be printed; notice hdc,
    # not dc, for DrawTextW uses a different handle, i have found this in other posts
    win32gui.DrawTextW (hdc, u"\u6C49\u5B57\u3001\u306B\u307B\u3093\u3054\u3001\u05E2\u05D1\u05E8\u05D9\u05EA\u3001\u0639\u0631\u0628\u064A\u6211\u90FD\u4F1A\u5237\u51FA\u3002", -1, (0, -2000, 4000, -4000), win32con.DT_CENTER)

except :
    traceback.print_exc()

# must not forget to tell Windows we're done. This line must get called if StartDoc 
# was called, if you fail to do so, your sys might start behaving unexpectedly
dc.EndDoc()


如何使用此代码打印 bmp 文件?我需要打印二维码 我有 bmp 文件 我收到此错误 - ( win32gui.DrawTextW(hdc, img, -1, (0, -2100, 4000, -4000), win32con.DT_CENTER) TypeError: Objects of type 'PilImage'无法转换为 Unicode。)

于 2021-04-21T18:45:11.420 回答