pdfrw文档很烂
这个问题的第一个答案中讨论的pdfrw示例有点笨拙的唯一原因是因为pdfrw文档很烂。由于苏茨基文档,这个例子的作者@拉里-
Meyn用于rst2pdf的vectorpdf扩展为为出发点,而 该 扩展是不是真的记录或者, 并
具有处理rst2pdf的怪癖以及pdfrw(和更超出您的需要,因为它可以使rst2pdf从预先存在的PDF的arbitray页显示任意矩形)。Larry设法使它工作起来真是太神奇了,而我的帽子也给了他。
我完全有资格这么说,因为我是pdfrw的作者,并且对rst2pdf做出了一些贡献,其中包括vectorpdf扩展名。
但是您可能还是想使用pdfrw
直到一个月前,我才真正开始关注stackoverflow,而pdfrw本身却停滞了好几年,但我现在就在这里,我认为您应该重新看一下pdfrw,即使文档仍然很烂。
为什么? 因为如果输出到png文件,则图像将被 栅格化 ,如果使用pdfrw,则图像将保持 矢量格式 ,这意味着它在任何比例下都看起来不错。
所以我修改了您答案的png示例
您的png示例不是一个完整的程序-尚未定义doc.build的参数,未定义样式,缺少一些导入等。但是它足够接近以获得一些意图并获得它加工。
编辑 - _我刚刚注意到该示例实际上是Larry的示例的修改版本,因此该示例仍然非常有价值,因为在某些方面它比此功能更全。
解决这些问题并获得一些输出后,我添加了一个能够使用png或pdf的选项,因此您可以看到区别。下面的程序将创建两个不同的PDF文件,您可以自己比较结果。
import cStringIOfrom matplotlib import pyplot as pltfrom reportlab.pdfgen import canvasfrom reportlab.lib.utils import ImageReaderfrom reportlab.platypus import Paragraph, SimpleDocTemplate, Spacer, Image, Flowablefrom reportlab.lib.units import inchfrom reportlab.lib.styles import getSampleStyleSheetfrom pdfrw import PdfReader, PdfDictfrom pdfrw.buildxobj import pagexobjfrom pdfrw.toreportlab import makerlstyles = getSampleStyleSheet()style = styles['Normal']def form_xo_reader(imgdata): page, = PdfReader(imgdata).pages return pagexobj(page)class PdfImage(Flowable): def __init__(self, img_data, width=200, height=200): self.img_width = width self.img_height = height self.img_data = img_data def wrap(self, width, height): return self.img_width, self.img_height def drawOn(self, canv, x, y, _sW=0): if _sW > 0 and hasattr(self, 'hAlign'): a = self.hAlign if a in ('CENTER', 'CENTRE', TA_CENTER): x += 0.5*_sW elif a in ('RIGHT', TA_RIGHT): x += _sW elif a not in ('LEFT', TA_LEFT): raise ValueError("Bad hAlign value " + str(a)) canv.saveState() img = self.img_data if isinstance(img, PdfDict): xscale = self.img_width / img.BBox[2] yscale = self.img_height / img.BBox[3] canv.translate(x, y) canv.scale(xscale, yscale) canv.doForm(makerl(canv, img)) else: canv.drawImage(img, x, y, self.img_width, self.img_height) canv.restoreState()def make_report(outfn, use_pdfrw): fig = plt.figure(figsize=(4, 3)) plt.plot([1,2,3,4],[1,4,9,26]) plt.ylabel('some numbers') imgdata = cStringIO.StringIO() fig.savefig(imgdata, format='pdf' if use_pdfrw else 'png') imgdata.seek(0) reader = form_xo_reader if use_pdfrw else ImageReader image = reader(imgdata) doc = SimpleDocTemplate(outfn) style = styles["Normal"] story = [Spacer(0, inch)] img = PdfImage(image, width=200, height=200) for i in range(10): bogustext = ("Paragraph number %s. " % i) p = Paragraph(bogustext, style) story.append(p) story.append(Spacer(1,0.2*inch)) story.append(img) for i in range(10): bogustext = ("Paragraph number %s. " % i) p = Paragraph(bogustext, style) story.append(p) story.append(Spacer(1,0.2*inch)) doc.build(story)make_report("hello_png.pdf", False)make_report("hello_pdf.pdf", True)这种方法有什么缺点?
第一个明显的缺点是,现在对pdfrw有要求,但是可以从PyPI获得。
下一个缺点是,如果您将大量matplotlib图放入文档中,我认为该技术将复制字体等资源,因为我认为reportlab不够聪明,无法注意到重复项。
我相信可以通过将所有图输出到单个PDF的不同页面来解决此问题。我实际上没有使用matplotlib尝试过,但是pdfrw完全能够将现有pdf的每一页转换为单独的flowable。
因此,如果您有很多图,并且使最终的PDF太大,则可以调查一下,或者只是尝试其中一种PDF优化器,看看是否有帮助。无论如何,在不同的日子里这是一个不同的问题。



