我有一个reportlab SimpleDocTemplate
,并将其作为动态PDF返回。我正在基于某些Django模型元数据生成内容。这是我的模板设置:
buff = StringIO()
doc = SimpleDocTemplate(buff, pagesize=letter,
rightMargin=72,leftMargin=72,
topMargin=72,bottomMargin=18)
Story = []
我可以轻松地将Entry
模型中的文本元数据添加到Story
列表中,稍后再构建:
ptext = '<font size=20>%s</font>' % entry.title.title()
paragraph = Paragraph(ptext, custom_styles["Custom"])
Story.append(paragraph)
然后通过在build
上调用SimpleDocTemplate
来生成要在响应中返回的PDF:
doc.build(Story, onFirstPage=entry_page_template, onLaterPages=entry_page_template)
pdf = buff.getvalue()
resp = HttpResponse(mimetype='application/x-download')
resp['Content-Disposition'] = 'attachment;filename=logbook.pdf'
resp.write(pdf)
return resp
模型上的一个元数据字段是文件附件。当这些文件附件为PDF时,我想将它们合并到我生成的Story中; IE表示reportlab“可流动”类型的PDF。
我正在尝试使用pdfrw
来执行此操作,但是没有任何运气。理想情况下,我只想致电:
from pdfrw import PdfReader
pdf = pPdfReader(entry.document.file.path)
Story.append(pdf)
并且如上所述,将pdf附加到要包含在最终文档生成中的现有Story列表中。
有人有什么想法吗?我尝试使用pagexobj创建pdf的类似方法,尝试遵循以下示例:
http://code.google.com/p/pdfrw/source/browse/trunk/examples/rl1/subset.py
from pdfrw.buildxobj import pagexobj
from pdfrw.toreportlab import makerl
pdf = pagexobj(PdfReader(entry.document.file.path))
但也没有任何运气。有人可以向我解释将现有PDF文件合并到可流动的reportlab中的最佳方法吗?我对这些东西不好,并且已经几天来一直在用pdf生成文件。 :)任何方向都非常感谢!
我刚刚在一个项目中有类似的任务。我使用reportlab(开源版本)生成pdf文件,并使用pyPDF进行合并。我的要求略有不同,因为每个附件只需要一页,但是我敢肯定,这可能足够接近您的总体思路。
from pyPdf import PdfFileReader, PdfFileWriter
def create_merged_pdf(user):
basepath = settings.MEDIA_ROOT + "/"
# following block calls the function that uses reportlab to generate a pdf
coversheet_path = basepath + "%s_%s_cover_%s.pdf" %(user.first_name, user.last_name, datetime.now().strftime("%f"))
create_cover_sheet(coversheet_path, user, user.performancereview_set.all())
# now user the cover sheet and all of the performance reviews to create a merged pdf
merged_path = basepath + "%s_%s_merged_%s.pdf" %(user.first_name, user.last_name, datetime.now().strftime("%f"))
# for merged file result
output = PdfFileWriter()
# for each pdf file to add, open in a PdfFileReader object and add page to output
cover_pdf = PdfFileReader(file( coversheet_path, "rb"))
output.addPage(cover_pdf.getPage(0))
# iterate through attached files and merge. I only needed the first page, YMMV
for review in user.performancereview_set.all():
review_pdf = PdfFileReader(file(review.pdf_file.file.name, "rb"))
output.addPage(review_pdf.getPage(0)) # only first page of attachment
# write out the merged file
outputStream = file(merged_path, "wb")
output.write(outputStream)
outputStream.close()
我使用以下课程来解决我的问题。它将PDF插入为矢量PDF图像。效果很好,因为我需要有一个目录。可流动的对象允许内置的TOC功能像超级按钮一样工作。
Is there a matplotlib flowable for ReportLab?
注意:如果文件中有多个页面,则必须稍加修改类。示例类旨在仅阅读PDF的第一页。
使用此自定义可流动对象:
class PDF_Flowable(Flowable):
#----------------------------------------------------------------------
def __init__(self,P,page_no):
Flowable.__init__(self)
self.P = P
self.page_no = page_no
#----------------------------------------------------------------------
def draw(self):
"""
draw the line
"""
canv = self.canv
pages = self.P
page_no = self.page_no
canv.translate(x, y)
canv.doForm(makerl(canv, pages[page_no]))
canv.restoreState()
然后打开现有的pdf,即后
pages = PdfReader(BASE_DIR + "/out3.pdf").pages
pages = [pagexobj(x) for x in pages]
for i in range(0, len(pages)):
F = PDF_Flowable(pages,i)
elements.append(F)
elements.append(PageBreak())
使用此代码在元素中添加此自定义可流动元素[]。