##language:zh #pragma section-numbers off ##含有章节索引导航的 ZPyUG 文章通用模板 <<TableOfContents>> ## 默许导航,请保留 <<Include(ZPyUGnav)>> = 文用 Reportlab 生成中文 PDF = {{{ Jiahua Huang <jhuangjiahua@gmail.com> reply-to python-cn@googlegroups.com to "Python.cn@google" <python-cn@googlegroups.com> date Fri, Aug 8, 2008 at 15:13 }}} subject [CPyUG:61808] 简单使用 Reportlab 生成中文 PDF 文档 ##startInc * 再次看到关于将 reStructurctedText、asciidoc、xhtml 转换为 PDF 格式的话题, * python 里用 Reportlab 应该比用 tex、docbook、fop 合适, 不过 python-reportlab 默认没中文字体,也没中文换行, * 而现有的使用 Reportlab 的程序改起来也麻烦, 便干脆用运行中修改的方式覆盖掉 reportlab.lib.fonts.ps2tt reportlab.lib.fonts.tt2ps reportlab.platypus.Paragraph.wrap 让强制用中文字体,强制尝试中文换行(,强制用 UTF-8 中文) * 好处是现有程序和库 (比如现有的那堆 rst2pdf、html2pdf、wiki2pdf 等程序) 不用做任何改动就可以中文, 缺陷是连英文也没粗体斜体了。 == 实例和分析 == * [[attachment:html2pdf.7z]] * 最新版本:'''[[http://openbookproject.googlecode.com/svn/tangle/html2pdf|html2pdf]]''' ^@ openbookproject.googlecode.com^ 添加:: * ## Hack for Chinese fonts ############################ {{{ #!python import reportlab.rl_config reportlab.rl_config.warnOnMissingFontGlyphs = 0 import reportlab.pdfbase.pdfmetrics import reportlab.pdfbase.ttfonts reportlab.pdfbase.pdfmetrics.registerFont(reportlab.pdfbase.ttfonts.TTFont('song', '/usr/share/fonts/truetype/wqy/wqy-zenhei.ttf')) import reportlab.lib.fonts reportlab.lib.fonts.ps2tt = lambda psfn: ('song', 0, 0) reportlab.lib.fonts.tt2ps = lambda fn,b,i: 'song' ## for CJK Wrap import reportlab.platypus def wrap(self, availWidth, availHeight): # work out widths array for breaking self.width = availWidth leftIndent = self.style.leftIndent first_line_width = availWidth - (leftIndent+self.style.firstLineIndent) - self.style.rightIndent later_widths = availWidth - leftIndent - self.style.rightIndent try: self.blPara = self.breakLinesCJK([first_line_width, later_widths]) except: self.blPara = self.breakLines([first_line_width, later_widths]) self.height = len(self.blPara.lines) * self.style.leading return (self.width, self.height) reportlab.platypus.Paragraph.wrap = wrap import sys reload(sys) sys.setdefaultencoding('utf8') }}} === 追加 pisa3 中文技巧 === 使用 pisa3 html2pdf 前插入下边语句 {{{#!python ## Hack for Chinese fonts ############################ 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', '/usr/share/fonts/truetype/wqy/wqy-zenhei.ttf')) from reportlab.lib import fonts fonts.ps2tt = lambda psfn: ('song', 0, 0) fonts.tt2ps = lambda fn,b,i: 'song' import reportlab.platypus def wrap(self, availWidth, availHeight): # work out widths array for breaking self.width = availWidth leftIndent = self.style.leftIndent first_line_width = availWidth - (leftIndent+self.style.firstLineIndent) - self.style.rightIndent later_widths = availWidth - leftIndent - self.style.rightIndent try: self.blPara = self.breakLinesCJK([first_line_width, later_widths]) except: #print 'breakLinesCJK except:',self, availWidth, availHeight self.blPara = self.breakLines([first_line_width, later_widths]) self.height = len(self.blPara.lines) * self.style.leading return (self.width, self.height) reportlab.platypus.Paragraph.wrap = wrap ## no zoomed for bookmarkPage import reportlab.pdfgen.canvas bookmarkPage = reportlab.pdfgen.canvas.Canvas.bookmarkPage reportlab.pdfgen.canvas.Canvas.bookmarkPage = lambda self, key, **kwargs: apply(bookmarkPage, (self, key), {'fit':'XYZ'}) ## for image import pisa_default; pisa_default.TAGS["img"][1]["src"] = (8, 23) #(STRING, MUST) import sys reload(sys) sys.setdefaultencoding('utf8') ######################################################## }}} == 使用和对比 == * '''UsageRstReportlabExPdf''' ~ 用 python-reportlab 将 rst 转换为中文 PDF * 实例输出: 1. [[attachment:usage-py-reportlab-rst-zhPDF_by_rst.pdf]] * {{attachment:snap-rst-zhPDF_by_rst.png}} 1. [[attachment:usage-py-reportlab-rst-zhPDF_by_OOo2.pdf]] * {{attachment:snap-rst-zhPDF_by_OOo2.png}} 1. [[attachment:usage-py-reportlab-rst-zhPDF_by_firefox.pdf]] * {{attachment:snap-rst-zhPDF_by_firefox.png}} ##endInc ---- '''反馈''' 创建 by -- ZoomQuiet [<<DateTime(2008-08-08T07:43:16Z)>>]