2012-06-28 43 views
0

我想使用Python程序从Excel .xls文件中读取一系列非西方(日文/中文)Unicode字符串,并创建一个每个字符串的图像文件。 xlrd模块为我提供了Excel文件中的Unicode字符串,它们在哪里正确显示。Python:使用Windows API创建日文/中文文本的Unicode渲染

previous question的回答提供了一些使用Python中的Windows API将普通的西文文本渲染为图像文件的基本元素。但是,如果我改变基本呼叫从一个Unicode文本字符串呈现2个日语字符为:

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

的代码失败:UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128)

在使用Windows API来正确显示Unicode字符串任何帮助将不胜感激。

回答

0

您需要使用Unicode版本的Win32Api。快速浏览另一个问题的链接,您至少需要win32gui.DrawTextW而不是Win32Font实施中的win32ui.DrawText。注意win32 g ui是本机API,而不是win32ui包装的MFC API。我没有看到在我的pywin32文档的快速查看中使用Unicode版本的MFC调用的方法,因此您需要使用GetSafeHdc将本地句柄从PyCDC中除去,以将其用于本地API。

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

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()