相关文章推荐

Python使用Reportlab处理PDF数据详解第2部分

背景知识视频教程



将数据转换为PDF


我们将尝试通过ReportLab复制该文档的布局。


您将创建的代码将支持基于XML数据文件中的数据量生成多页报告。 让我们看看如何!


通常,客户端会给您一个数据文件以及他们希望您从该文件生成的输出。 有时,您将需要设计自己的规范以供客户端使用,但我很少遇到这种情况。 接收数据文件和报告时,要做的第一件事是确定各种数据在报告中的位置。 在这种情况下,这些片段将在XML标签中,因此它们实际上将被标记。 这使事情变得容易得多,尤其是在XML具有良好标签名称的情况下。 固定宽度的数据文件更加困难,因为它们没有命名字段,您可以一目了然。


一旦确定了现有文档中的所有内容,就可以开始创建一些代码了。 每个开发人员都是不同的。 您可以从此时开始为XML编写解析器开始。 或者,您可以尝试使用一些硬编码的值来布局文档。 解析器和布局代码应该位于单独的模块中,因此,首先完成哪种功能并不重要。


让我们开始设计报告,方法是创建一个可以使用的基类。 我们将列出一些我们认为也将需要的方法。 将以下代码保存到名为eob.py的文件中:

from reportlab.lib.pagesizes import letter
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.pdfgen import canvas
from reportlab.platypus import SimpleDocTemplate, Paragraph, Table
from reportlab.lib.units import inch, mm
class EOB:
    Explanation of Benefits PDF Class
  def __init__(self, pdf_file):
  ''''''
        self.canvas = canvas.Canvas(pdf_file, pagesize=letter)
        self.styles = getSampleStyleSheet()
        self.width, self.height = letter
  def coord(self, x, y, unit=1):
        x, y = x * unit, self.height -   y * unit
  return x, y
  def create_header(self):
  ''''''
  def create_payment_summary(self):
  ''''''
  def create_claims(self):
  ''''''
  def save(self):
  ''''''
        self.canvas.save()
def main(pdf_file):
  ''''''
    eob = EOB(pdf_file)
    eob.save()
if __name__ == '__main__':
    pdf_file = 'eob.pdf'
    main(pdf_file)


您会注意到,对于我们第一次尝试生成(EOB)的过程,我们使用ReportLab的canvas模块。 您也可以从platypus开始,但为简单起见,我们将从画布开始,然后在需要时将其更新为使用platypus。 __init__方法是我们创建画布实例的地方。 我们还创建一些类属性来定义页面的宽度和高度。 您还将注意到,我们创建了样式表,将其用于设置段落的样式。


我们创建的下一个方法称为coord。 我们将使用此方法最终帮助我们在页面上定位元素。


接下来,我们创建三个存根方法:create_header,create_payment_summary和create_claims。 这些方法现在不执行任何操作。 最后一种方法是我们的保存方法,它仅将PDF保存到磁盘。


最后,我们有main函数。 在这里,我们创建EOB实例并告诉它保存。 这段代码会生成一个空的PDF,这并不是很有趣。 因此,让我们通过更新create_header方法使代码做一些有用的事情:


def create_header(self):
  ''''''
    ptext = '<font size=10><b>Statement Date: {}' \
  '</b></font>'.format('01/01/2017')
    p = Paragraph(ptext, self.styles['Normal'])
    p.wrapOn(self.canvas, self.width, self.height)
    p.drawOn(self.canvas, *self.coord(145, 17, mm))
    ptext = '''<font size=10>
    <b>Member:</b> {member}<br/>
    <b>Member ID:</b> {member_id}<br/>
    <b>Group #:</b> {group_num}<br/>
    <b>Group name:</b> {group_name}<br/>
    </font>
    '''.format(member='MIKE D',
               member_id='X123456',
               group_num=789456-1235,
               group_name='PYTHON CORP'
    p = Paragraph(ptext, self.styles['Normal'])