[reportlab教程](3) – 中文的处理

让我们进入中文的处理过程吧。

原本看到 ReportLab 的 test 目录下有一个 test_multibyte_chs.py ,试了试效果不错,就以为中文问题照猫画虎应该没什么问题呀。但等我再仔细深入后,发现问题不那么简单。

问题一:无法使用Paragraph。因示例中使用的是底层的API,因此对于字体要求不高。而使用Paragraph需要知道粗体、斜体、粗斜体这些字体,而示例中并没有这样的处理。

问题二:在解了上面的问题之后,发现中文只有一种字体,实现不了斜体和粗体效果。

现在我已经基本解决了上面的问题,但是无法实现斜体和粗斜体,这个以后再看一看吧。

中文处理方法一

这种方法采用示例中的方式,即使用CID字体,代码如下:

#coding=gbk
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.cidfonts import CIDFont, CIDTypeFace, findCMapFile
enc = ‘GB-EUC-H’
findCMapFile(enc)
face = CIDTypeFace(‘STSong-Light’)
pdfmetrics.registerTypeFace(face)
pdfmetrics.registerFont(CIDFont(‘STSong-Light’,enc))
from reportlab.lib import fonts
fonts.addMapping(‘STSong-Light’, 0, 0, ‘STSong-Light’)
fonts.addMapping(‘STSong-Light’, 0, 1, ‘STSong-Light’)
fonts.addMapping(‘STSong-Light’, 1, 0, ‘STSong-Light’)
fonts.addMapping(‘STSong-Light’, 1, 1, ‘STSong-Light’)

import copy

from reportlab.platypus import Paragraph, SimpleDocTemplate, PageBreak
from reportlab.lib.styles import getSampleStyleSheet
stylesheet=getSampleStyleSheet()
normalStyle = copy.deepcopy(stylesheet['Normal'])
normalStyle.fontName =’STSong-Light-GB-EUC-H’
normalStyle.fontSize = 20
story = []
story.append(Paragraph("<b>你好</b>,中文", normalStyle))
doc = SimpleDocTemplate(‘hello.pdf’)
doc.build(story)


使用CID字体只有STSong-Light一种字体可用,而我查看资料看到其它的如Big5都有两种字体,真是气人。前面说到问题一,需要使用fonts.addMapping来解决,即分别注册四种字形。addMapping共有四个参数,第一个是以后引用的字体名,第二个是粗体标志,第三个是斜体标志,第四个是对应的字体名称。因此上面增加了四种字形。而所用到的字体应该调用pdfmetrics.registerFont()进行字体的注册。而且在实际运行时发现,光注册字体还不够,还要注册TypeFace。在所有字体注册完毕后,下面可以真正中文的测试了。
normalStyle = copy.deepcopy(stylesheet['Normal']) 
normalStyle.fontName =’STSong-Light-GB-EUC-H’ 
normalStyle.fontSize = 20


这里是设置段落将使用的字体名称。很奇怪,字体名称是前面注册的字形名与编码的合并。

运行上面的示例中文文件就生成了。但如果加入英文,也是使用中文字符进行显示的。注意,上面的文件编码设置为gbk

这种方法目前来说我认为并不好,那么好在还有第二种方法。

中文处理的第二种方法

这种方法使用直接处理TrueType字体的方法,但在测试过程中速度有些慢。但好处是可以使用中文的字体文件,当然需要是ttf格式的文件。这样可以引入更多的字体了。代码如下:

#coding=utf-8
import reportlab.rl_config
reportlab.rl_config.warnOnMissingFontGlyphs = 0
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfgen import canvas
pdfmetrics.registerFont(TTFont(’song’, ‘SURSONG.TTF’))
pdfmetrics.registerFont(TTFont(‘hei’, ‘SIMHEI.TTF’))

from reportlab.lib import fonts
fonts.addMapping(’song’, 0, 0, ’song’)
fonts.addMapping(’song’, 0, 1, ’song’)
fonts.addMapping(’song’, 1, 0, ‘hei’)
fonts.addMapping(’song’, 1, 1, ‘hei’)

import copy

from reportlab.platypus import Paragraph, SimpleDocTemplate, PageBreak
from reportlab.lib.styles import getSampleStyleSheet
stylesheet=getSampleStyleSheet()
normalStyle = copy.deepcopy(stylesheet['Normal'])
normalStyle.fontName =’song’
normalStyle.fontSize = 20
story = []
story.append(Paragraph(‘<b>你好</b>,中文’, normalStyle))
doc = SimpleDocTemplate(‘hello.pdf’)
doc.build(story)


处理方法与方法一差不多,主要差别在红色的字部分。文件编码注意是utf-8,而不是gbk了。我是在运行时发现的,使用utf-8,然后直接使用中文就可以,不然就没东西。字体还是要注册,但不是使用CIDFont了,而是使用TTFont来处理了。而且不需要注册TypeFace了。再注册字形,这里我对于粗体字形使用了黑体字。最后对于样式使用字体时,只要使用简单的字形名即可,不再象第一种方法还需要加入编码名称。

上面的处理可以解决正常和粗体的字形,但斜体还是无法支持,但已经好多了。而且好处是可以使用其它的中文字体比如仿宋了,彩云体了。

不过在处理英文时还是存在问题。如果不加特殊处理英文会转变为汉字,的确不好看。那么你可以在段落中加入<font>标签,设置name为想用的英文字体即可。与HTML的标签差不多。但发现所有英文自动变成斜体了。不知道为什么。现在知道一个解决的方法就是不修改样式中的字体名,而是在文本中加入<font>标签来设置中文字体,但这样就比较麻烦。当然通过程序来做麻烦也不怕。比如:

normalStyle = copy.deepcopy(stylesheet['Normal']) 
#normalStyle.fontName =’song’ 
normalStyle.fontSize = 20 
story = [] 
story.append(Paragraph(‘<font name="hei">你好</font>,<font name="song">中文</font>’, normalStyle)) 
doc = SimpleDocTemplate(‘hello.pdf’) 
doc.build(story)

大家有兴趣可以试一试。

采用的第二种方法,测试成功,需要下载TTF文件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值