学习利用ReportLab生成PDF报表 -- 准备工作及Demo
2017-04-06 16:26
591 查看
官方Demo
官网提供了一个demo,下载地址:
http://www.reportlab.com/static/cms/files/RLtutorial.zip
在运行前需要安装相关的依赖包。在ReportLab网站注册并登陆后会有更完整的文档。
rlextra: 安装该包前需要注册ReportLab用户,登陆后才能下载。
官网提供了一个demo,下载地址:
http://www.reportlab.com/static/cms/files/RLtutorial.zip
在运行前需要安装相关的依赖包。在ReportLab网站注册并登陆后会有更完整的文档。
rlextra: 安装该包前需要注册ReportLab用户,登陆后才能下载。
pip install rlextra -i https://www.reportlab.com/pypi[/code]
在下载完成rlextra后会自动下载其他依赖包。
preppy: 一种预处理程序,利用其来读取模板template。
参考: https://bitbucket.org/rptlab/preppy
reportlab
pyRXP
等等
安装完成相关包后执行文件夹下product_catalog.py,仍发现有很多错误,主要集中在编码,StringIO/BytesIO(Demo文件中是用了StringIO作为buf,但执行报错,查看相关源码文件后发现需要用BytesIO。)上,除此之外Demo中的数据是通过解析XML文件得到的,可能以后使用中不会使用XML来获取数据,所以决定自己重新写一个新的Demo。
自己编写的SimpleDemo
简单的生成一份pdf报表主要需要三方面的准备:数据,模板文件(prep, rml),相关简单工具方法。编写模板文件和数据准备相比较更重要,更繁琐,而简单的编写工具方法比较轻松,不过后期肯定需要优化。
数据: 从mongodb数据库中获取。
模板文件: 利用RML(Report Markup Language)编写模板,可在其中嵌套Python代码,详细文档可登陆ReportLab后下载。下面是一个最基本的RML模板(取自官方RML2PDF with Django Demo):<!DOCTYPE document SYSTEM "rml.dtd"> <document filename="hello.pdf"> <template showBoundary="0"> <pageTemplate id="main"> <frame id="first" x1="50" y1="200" width="450" height="300"/> </pageTemplate> </template> <stylesheet> <paraStyle name="textstyle1" fontName="Helvetica" fontSize="24" leading="24" /> </stylesheet> <story> <para style="textstyle1"> Welcome<b>{{name}}<b>, to the world of RML! </para> </story> </document>
相关简单工具方法:from rlextra.rml2pdf import rml2pdf import preppy from io import BytesIO class PDFUtils(object): def __init__(self, template_name, namespace, output_filename=None): self.template_name = template_name self.namespace = namespace self.output_filename = output_filename # 其他相关操作(注册字体等) def create_pdf(self): source_text = open(self.template_name, 'r', encoding='utf-8').read() template = preppy.getModule(self.template_name, sourcetext=source_text) # template = preppy.getModule(self.template_name) rml = template.getOutput(self.namespace) if self.output_filename: rml2pdf.go(rml, outputFileName=self.output_filename) return True else: buf = BytesIO() rml2pdf.go(rml, outputFileName=buf) pdf_data = buf.getvalue() return pdf_data
需要注意的是,若要输出IO流(如web请求时下载pdf报表文件),这里用的是BytesIO。若像官方Demo中用StringIO,在执行rml2pdf.go()时会抛出TypeError: string argument expected, got 'bytes'异常,查看文件pdfdoc.py源码:data = self.GetPDFData(canvas) if isUnicode(data): data = data.encode('latin1') f.write(data)
这里self.GetPDFData(canvas)返回的是bytes,在f.write()时需要BytesIO类型。(暂时不知道其他解决办法)
除此之外,在利用preppy.getModule()解析rml文件时,若rml文件中出现中文字符直接利用preppy.getModule(template_name)会出现gbk无法解析中文的情况,查看源码发现当只有一个name参数时,getModule()会默认open(name, 'r').read()出现UnicodeDecodeError。所以使用利用sourcetext参数,先按指定编码读取文件内容再解析,即source_text = open(template_name, 'r', encoding='utf-8').read() template = preppy.getModule(template_name, sourcetext=source_text),同时需要在rml文件中注册中文字体。
main():if __name__ == '__main__': # 模板文件 template = 'hello.rml' # 输出的pdf output_filename = 'output/simple_demo.pdf' # 数据 namespace = { 'name': 'JiangW' } p = PDFUtils(template, namespace, output_filename=output_filename) p.create_pdf()
相关文章推荐
- 学习利用ReportLab生成PDF报表 -- RML基础(The Basics)
- 学习利用ReportLab生成PDF报表 -- 图表
- 如何利用iText在JSP中生成PDF报表
- 利用iText在JSP中生成PDF报表
- C#利用ZedDemo组件生成数据报表
- 详解如何利用iText在JSP中生成PDF报表
- 利用iText在JSP中生成PDF报表
- 利用iText在JSP中生成PDF报表
- 利用jasperreports报表生成pdf文档中文不能显示问题解决方法
- 利用iText生成PDF报表
- 详解如何利用iText在JSP中生成PDF报表
- 详解如何利用iText在JSP中生成PDF报表
- 如何利用iText在JSP中生成PDF报表- -
- django学习之 pdf报表(表格)生成
- 利用iText在JSP中生成PDF报表
- C#利用ZedDemo组件生成数据报表
- 利用iText在JSP中生成PDF报表
- 利用iText在JSP中生成PDF报表
- 利用iText在JSP中生成PDF报表
- 利用iText生成pdf报表