Python 使用画布绘制图像并使用SimpleDoctTemplate

Python 使用画布绘制图像并使用SimpleDoctTemplate,python,django,reportlab,Python,Django,Reportlab,我在django视图中使用reportlab编写PDF,它们非常简单,包括页眉、内容和页脚 我使用SimpleDoctTemplate,它非常适合在目录中绘制表格,页脚和页眉使用: build([data], onFirstPage=drawPageFrame, onLaterPages=drawPageFrame). 我的问题是,如何使用Canvas.drawImage(…)绘制图像?我需要一个“浮动”图像。。。放置在我想要的文本上,使用SimpleDoctTemplate,我没有画布对象来

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

我使用SimpleDoctTemplate,它非常适合在目录中绘制表格,页脚和页眉使用:

build([data], onFirstPage=drawPageFrame, onLaterPages=drawPageFrame).
我的问题是,如何使用Canvas.drawImage(…)绘制图像?我需要一个“浮动”图像。。。放置在我想要的文本上,使用SimpleDoctTemplate,我没有画布对象来完成这项工作

搜索时,我发现了以下内容:

鸭嘴兽布局使用可流动性。封隔器通常设置封隔器 在包装、拆分或删除每个流时,将canv属性添加到每个流上 围绕包裹、拆分和绘制方法绘制ie。在这些方法中 您可以使用self的canv属性访问画布

这个怎么用

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

flowables.Macro
flowables.CallerMacro
#-*-编码:utf-8-*- 从reportlab.lib.pagesizes导入A4、横向、纵向 从reportlab.lib.styles导入getSampleStyleSheet 来自reportlab.platypus导入表,可流动,简化模板,段落,间隔符,图像 从reportlab.lib导入随机文本 从reportlab导入鸭嘴兽 导入操作系统,随机 styles=getSampleStyleSheet() path=os.path.realpath(os.path.dirname(_文件__)) def drawPageFrame(画布、文档): canvas.saveState() canvas.drawImage(path+“/ujiPDF.jpg”,50,50,57,57) canvas.restoreState() doc=SimpleDocTemplate(“salida.pdf”,pagesize=A4) elementos=[] com='canvas.drawImage('+path+'/ujiPDF.jpg',100100,57,57)' 打印通讯 append(platypus.flowables.Macro('canvas.saveState()')) 打印platypus.flowables.Macro(com) elementos.append(platypus.flowables.Macro(com)) elementos.append(platypus.flowables.Macro('canvas.restoreState()')) para=段落(randomtext.randomtext(randomtext.PYTHON,20),样式[“Normal”]) 附加要素(第2段) doc.build(elementos,onFirstPage=drawPageFrame,onLaterPages=drawPageFrame)
这是宏方法…清除退出,但没有第二个映像。

您最好的选择是创建SimpleDoctTemplate或BasedDoctTemplate的子类。在build方法中,您可以访问画布。如果您想利用SimpleDoctTemplate所做的一切,您可以尝试直接从
站点包/reportlab/platypus/doctemplate.py

复制它,platypus中有Image类。只需使用reportlab.platypus import Image中的
,您就可以访问该类。它的工作原理与内部的其他类类似,
smth.append(Image(filename))
将图像附加到需要构建到pdf中的对象。创建于

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

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

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

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

导入matplotlib.pyplot作为plt
导入cStringIO
从reportlab.lib.units导入英寸,厘米
从reportlab.lib.pagesizes导入信函
从reportlab.platypus导入SimpleDoctTemplate、段落、间隔符、图像、表格
从reportlab.lib.styles导入getSampleStyleSheet、ParagraphStyle
导入reportlab.lib、reportlab.platypus
类流动图(reportlab.platypus.flowable):
定义初始化(自我,imgdata):
reportlab.platypus.Flowable.\uuuuuu init\uuuuuuuuu(自身)
self.img=reportlab.lib.utils.ImageReader(imgdata)
def牵引(自):
self.canv.drawImage(self.img,0,0,高度=-2*英寸,宽度=4*英寸)
# http://www.reportlab.com/apis/reportlab/2.4/pdfgen.html
doc=SimpleDocTemplate((“report.pdf”),pagesize=letter,
右边距=72,左边距=72,
上边缘=72,下边缘=18)
故事=[]
styles=getSampleStyleSheet()
ptext='Lorem ipsum door sit amet,奉献精英。莫比·马萨·多洛,秃鹫精英,圣射手。在欧洲,欧洲最大的前庭矢状体前庭不在同一区域内。佩朗斯特·奥纳雷·维利特·安特·乌兰科珀(ante ullamcorper)是一位腐败的罪魁祸首。多洛尔码头酒店。亨德雷特(Phasellus hendrerit)、普雷蒂姆(ligula vel concertetur pretium)、厄洛斯(lorem neque dapibus eros)、奥纳(ornare suscipit ipsum dolor id nisl)。这是一个非常有效的方法。不可否认的是,它是一种权杖,是一种特殊的知识,是一种先天不足的封建精神。纳姆·洛博蒂斯,佩伦特斯式的封建主义者,奥库·奥奇·鲁图姆·费利斯,努拉的卢克图斯·乌尔纳·尼斯。在ac麦格纳酒店,为您提供便利设施。乌尔里希斯梅特斯酒店。塞德苏打水、自由维维拉肉酱、麦格纳啤酒、欧盟调味品玉米饼或蒂尼迪蒙特turpis。前庭权杖。这是欧盟前萨吉蒂人的共同愿望
附加(段落(ptext,样式[“正常”]))
图=plt.图(图尺寸=(10,3))
plt.绘图([1,2,3,4])
plt.ylabel('这是一个无聊的情节')
imgdata=cStringIO.StringIO()
图.savefig(imgdata,format='png')
imgdata.seek(0)#倒带数据
pic=可流动图(imgdata)
故事追加(图)

doc.build(Story)
抱歉,我还不能尝试您的解决方案,但我发现了两种方法,我认为它们更适合我的紫色,flowables.Macro和flowables.CallerMacro,当我尝试所有方法时,我会发布最终的解决方案,无论如何,谢谢!。嗯,阅读代码,SimpleDocTemp # -*- coding: utf-8 -*- from reportlab.lib.pagesizes import A4, landscape, portrait from reportlab.lib.styles import getSampleStyleSheet from reportlab.platypus import Table, Flowable, SimpleDocTemplate, Paragraph, Spacer, Image from reportlab.lib import randomtext from reportlab import platypus import os,random styles = getSampleStyleSheet() path = os.path.realpath(os.path.dirname(__file__)) def drawPageFrame(canvas, doc): canvas.saveState() canvas.drawImage(path+"/ujiPDF.jpg",50,50,57,57) canvas.restoreState() doc = SimpleDocTemplate("salida.pdf",pagesize=A4) elementos = [] com = 'canvas.drawImage("'+path+'/ujiPDF.jpg",100,100,57,57)' print com elementos.append(platypus.flowables.Macro('canvas.saveState()')) print platypus.flowables.Macro(com) elementos.append(platypus.flowables.Macro(com)) elementos.append(platypus.flowables.Macro('canvas.restoreState()')) para = Paragraph(randomtext.randomText(randomtext.PYTHON,20), styles["Normal"]) elementos.append(para) doc.build(elementos,onFirstPage=drawPageFrame, onLaterPages=drawPageFrame)