##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)>>]