7

我在 django 视图中使用 reportlab 编写 pdf,它们非常简单,包括页眉、内容和页脚。

我正在使用 SimpleDocTemplate 非常适合,在内容中绘制表格,页脚和页眉是 drwan 使用:

build([data], onFirstPage=drawPageFrame, onLaterPages=drawPageFrame).

我的问题是,如何像使用 Canvas.drawImage(...) 一样绘制图像?我需要一个“浮动”图像......定位在我想要的文本上,并且使用 SimpleDocTemplate 我没有 Canvas 对象来执行此操作。

搜索我发现了这个:

鸭嘴兽布局的东西使用 flowables。打包程序通常在每个可流动对象被包装、拆分或绘制时设置属性 canv ,即围绕 wrap、split 和 draw 方法。在这些方法中,您可以使用 self 的 canv 属性访问画布。

这个怎么用?

嗯,还有更多要测试的东西:

flowables.Macro
flowables.CallerMacro
# -*- 编码:utf-8 -*-
从 reportlab.lib.pagesizes 导入 A4、横向、纵向
从 reportlab.lib.styles 导入 getSampleStyleSheet
从 reportlab.platypus 导入 Table、Flowable、SimpleDocTemplate、Paragraph、Spacer、Image
从 reportlab.lib 导入随机文本
从reportlab导入鸭嘴兽

导入操作系统,随机

样式 = getSampleStyleSheet()
路径 = os.path.realpath(os.path.dirname(__file__))

def drawPageFrame(画布,文档):
    canvas.saveState()
    canvas.drawImage(path+"/ujiPDF.jpg",50,50,57,57)
    canvas.restoreState()

doc = SimpleDocTemplate("salida.pdf",pagesize=A4)

元素 = []

com = 'canvas.drawImage("'+path+'/ujiPDF.jpg",100,100,57,57)'
印刷公司
elementos.append(platypus.flowables.Macro('canvas.saveState()'))
打印 platypus.flowables.Macro(com)
elementos.append(platypus.flowables.Macro(com))
elementos.append(platypus.flowables.Macro('canvas.restoreState()'))

para = Paragraph(randomtext.randomText(randomtext.PYTHON,20),样式["Normal"])
elementos.append(para)

doc.build(elementos,onFirstPage=drawPageFrame, onLaterPages=drawPageFrame)

这是宏方法...干净退出但没有第二张图像。

4

3 回答 3

10

如果我理解正确,您不需要对整个文档模板进行子类化,您只需要一个可以放入 SimpleDocTemplate 的可流动对象。您可以通过 Flowable 本身的一个非常简单的子类来实现这一点。

-> 特别是因为人们经常询问如何将 matplotlib 对象放入 reportlab,我将展示如何使用 matplotlib 生成绘图,然后使用修改后的 flowable 将该绘图放入 SimpleDocTemplate(不将文件保存到磁盘)。该概念适用于任何文件或您可以输入 cStringIO 的任何内容

-> 下面确实允许您将图形放在文本上(将高度从负数更改为正数,以将其推到绘图进入的部分顶部的假想线上方)

关键概念是每个 Flowable 本身也包含一个我们可以绘制的画布。

import matplotlib.pyplot as plt
import cStringIO
from reportlab.lib.units import inch, cm
from reportlab.lib.pagesizes import letter
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Image, Table
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
import reportlab.lib, reportlab.platypus

class flowable_fig(reportlab.platypus.Flowable):
    def __init__(self, imgdata):
        reportlab.platypus.Flowable.__init__(self)
        self.img = reportlab.lib.utils.ImageReader(imgdata)

    def draw(self):
        self.canv.drawImage(self.img, 0, 0, height = -2*inch, width=4*inch)
        # http://www.reportlab.com/apis/reportlab/2.4/pdfgen.html
                            
doc = SimpleDocTemplate(("report.pdf"),pagesize=letter,
                    rightMargin=72,leftMargin=72,
                    topMargin=72,bottomMargin=18)
Story=[]
styles=getSampleStyleSheet()
ptext = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi massa dolor, vulputate quis elit sed, sagittis consectetur erat. Sed lobortis nisi eros, eu maximus enim iaculis ac. Vestibulum sagittis urna nec interdum aliquam. Pellentesque ornare velit ut ante ullamcorper, vulputate accumsan nisi vulputate. Fusce consectetur dolor quam. Phasellus hendrerit, ligula vel consectetur pretium, lorem neque dapibus eros, ornare suscipit ipsum dolor id nisl. Sed vel orci id leo efficitur lobortis sit amet id risus. Nullam euismod, ipsum a posuere scelerisque, ante lorem ultrices nibh, ut feugiat metus ex congue enim. Nam lobortis, metus id pellentesque feugiat, arcu orci rutrum felis, quis luctus urna nisl at nulla. Donec eu eros pharetra dolor congue facilisis at ac magna. Nullam eu ultricies metus. Sed sodales, libero viverra pellentesque tempus, magna purus convallis nibh, eu condimentum tortor erat tincidunt turpis. Vestibulum scelerisque tincidunt egestas. Nullam commodo diam nisl, sed consequat ex sagittis eu.'
Story.append(Paragraph(ptext, styles["Normal"]))

fig = plt.figure(figsize=(10, 3))
plt.plot([1,2,3,4])
plt.ylabel('This is a boring plot')
imgdata = cStringIO.StringIO()
fig.savefig(imgdata, format='png')
imgdata.seek(0)  # rewind the data

pic = flowable_fig(imgdata)
Story.append(pic)
doc.build(Story)

你可以扩展这个最小的代码片段来完成你喜欢的任何事情,你可以将尽可能多的片段添加到 Story 变量中(这实际上只是一个可流动的列表)。神奇之处在于我们向文档生成器提供了一个 Flowable,它使用 Flowable 自己的画布来绘制图形。

编辑:我差点忘了,因为这让我们可以完全访问 drawImage,我们还可以使该图片或绘图具有透明度,以便可以通过它看到其他内容。drawImage 上的文档有详细信息。

于 2015-02-08T00:18:10.073 回答
6

鸭嘴兽中有Image类。只需使用from reportlab.platypus import Image ,您就可以访问该课程。它与内部的其他类一样工作,smth.append(Image(filename))并将图像附加到您需要构建到 pdf 中的对象。创立于Tyler Lessman 个人网站

于 2012-12-25T10:29:21.717 回答
3

您最好的选择是创建 SimpleDocTemplate 或 BaseDocTemplate 的子类。在构建方法中,您将可以访问画布。如果您想利用 SimpleDocTemplate 所做的一切,您可以尝试直接从site-packages/reportlab/platypus/doctemplate.py.

于 2011-03-19T15:14:14.920 回答