debian-pdfrw/examples/rl1/platypus_pdf_template.py

109 lines
3.6 KiB
Python
Executable File

#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
usage: platypus_pdf_template.py source.pdf
Creates platypus.source.pdf
Example of using pdfrw to use page 1 of a source PDF as the background
for other pages programmatically generated with Platypus.
Contributed by user asannes
"""
import sys
import os
from reportlab.platypus import PageTemplate, BaseDocTemplate, Frame
from reportlab.platypus import NextPageTemplate, Paragraph, PageBreak
from reportlab.platypus.tableofcontents import TableOfContents
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.rl_config import defaultPageSize
from reportlab.lib.units import inch
from reportlab.graphics import renderPDF
from pdfrw import PdfReader
from pdfrw.buildxobj import pagexobj
from pdfrw.toreportlab import makerl
PAGE_WIDTH = defaultPageSize[0]
PAGE_HEIGHT = defaultPageSize[1]
class MyTemplate(PageTemplate):
"""The kernel of this example, where we use pdfrw to fill in the
background of a page before writing to it. This could be used to fill
in a water mark or similar."""
def __init__(self, pdf_template_filename, name=None):
frames = [Frame(
0.85 * inch,
0.5 * inch,
PAGE_WIDTH - 1.15 * inch,
PAGE_HEIGHT - (1.5 * inch)
)]
PageTemplate.__init__(self, name, frames)
# use first page as template
page = PdfReader(pdf_template_filename).pages[0]
self.page_template = pagexobj(page)
# Scale it to fill the complete page
self.page_xscale = PAGE_WIDTH/self.page_template.BBox[2]
self.page_yscale = PAGE_HEIGHT/self.page_template.BBox[3]
def beforeDrawPage(self, canvas, doc):
"""Draws the background before anything else"""
canvas.saveState()
rl_obj = makerl(canvas, self.page_template)
canvas.scale(self.page_xscale, self.page_yscale)
canvas.doForm(rl_obj)
canvas.restoreState()
class MyDocTemplate(BaseDocTemplate):
"""Used to apply heading to table of contents."""
def afterFlowable(self, flowable):
"""Adds Heading1 to table of contents"""
if flowable.__class__.__name__ == 'Paragraph':
style = flowable.style.name
text = flowable.getPlainText()
key = '%s' % self.seq.nextf('toc')
if style == 'Heading1':
self.canv.bookmarkPage(key)
self.notify('TOCEntry', [1, text, self.page, key])
def create_toc():
"""Creates the table of contents"""
table_of_contents = TableOfContents()
table_of_contents.dotsMinLevel = 0
header1 = ParagraphStyle(name='Heading1', fontSize=16, leading=16)
header2 = ParagraphStyle(name='Heading2', fontSize=14, leading=14)
table_of_contents.levelStyles = [header1, header2]
return [table_of_contents, PageBreak()]
def create_pdf(filename, pdf_template_filename):
"""Create the pdf, with all the contents"""
pdf_report = open(filename, "wb")
document = MyDocTemplate(pdf_report)
templates = [MyTemplate(pdf_template_filename, name='background')]
document.addPageTemplates(templates)
styles = getSampleStyleSheet()
elements = [NextPageTemplate('background')]
elements.extend(create_toc())
# Dummy content (hello world x 200)
for i in range(200):
elements.append(Paragraph("Hello World" + str(i), styles['Heading1']))
document.multiBuild(elements)
pdf_report.close()
if __name__ == '__main__':
template, = sys.argv[1:]
output = 'platypus_pdf_template.' + os.path.basename(template)
create_pdf(output, template)