使用画布绘制图像并使用SimpleDocTemp

2024-04-29 15:55:30 发布

您现在位置:Python中文网/ 问答频道 /正文

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

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

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

我的问题是,我怎样才能像使用Canvas.draw image(…)那样绘制图像?我需要一个“浮动”图像。。。放置在我想要的文本上,并且使用SimpleDocTemplate,我没有画布对象来执行此操作。

搜索我找到了这个:

The platypus layout stuff uses flowables. Packers normally set the attribute canv onto each flowable when it is being wrapped, split or drawn ie around the wrap, split and draw methods. Inside those methods you have access to the canvas using the canv attribute of self.

这个怎么用?

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

flowables.Macro
flowables.CallerMacro
# -*- 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)

这是一个宏方法…干净的出口,但没有第二个图像。


Tags: thepathfrom图像importcomcanvasmacro
3条回答

鸭嘴兽有图像类。只要使用from reportlab.platypus import Image就可以访问这个类。它的工作方式与内部的其他类类似,smth.append(Image(filename))将图像附加到需要构建为pdf的对象。成立于Tyler Lessman personal website

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

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

->;下面允许您将图形放在文本上(将高度从负值更改为正值,将其推到绘图所进入部分顶部的虚线上方)

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

&13;
&13;
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变量添加尽可能多的片段(实际上,Story变量只是一个可流动的列表)。神奇的是,我们给doc builder一个Flowable,它使用Flowable自己的画布来绘制图形。

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

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

相关问题 更多 >