Official links:
Codebase links:
Community links:
from io import BytesIO | |
from reportlab.lib.enums import TA_JUSTIFY | |
from reportlab.lib.pagesizes import letter | |
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle | |
from reportlab.platypus import BaseDocTemplate, Paragraph, Spacer, PageTemplate, Frame | |
# Common text | |
LOREM = ( | |
"Lorem Ipsum is simply dummy text of the printing and typesetting industry. " | |
"Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, " | |
"when an unknown printer took a galley of type and scrambled it to make a type " | |
"specimen book. It has survived not only five centuries, but also the leap into " | |
"electronic typesetting, remaining essentially unchanged. It was popularised in " | |
"the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, " | |
"and more recently with desktop publishing software like Aldus PageMaker including " | |
"versions of Lorem Ipsum." | |
) | |
HELLO = "Hello World is another language" | |
HELLO_MULTI = ". ".join([HELLO for _ in range(40)]) + "." | |
# Common styles | |
STYLES = getSampleStyleSheet() | |
STYLES.add(ParagraphStyle(name="Justify", alignment=TA_JUSTIFY)) | |
NORM_STYLE = STYLES["Normal"] | |
H1_STYLE = STYLES["Heading1"] | |
def context(canvas, doc): | |
"""Establish header and footer contexts.""" | |
canvas.saveState() | |
# Establish header | |
P = build_p("This is a multi-line header. It goes on every page. " * 5, font_size=6) | |
w, h = P.wrap(doc.width, doc.topMargin) | |
P.drawOn(canvas, doc.leftMargin, doc.height + doc.topMargin) | |
# Establish footer | |
P = build_p("This is a multi-line footer. It goes on every page. " * 5, font_size=6) | |
w, h = P.wrap(doc.width, doc.bottomMargin) | |
P.drawOn(canvas, doc.leftMargin, h) | |
canvas.restoreState() | |
def build_text(content: str, font_size: int = 8): | |
"""Build text with certain font.""" | |
pre = f"<font size={font_size}>" | |
post = "</font>" | |
return pre + content + post | |
def build_p(content: str, font_size: int = 8): | |
"""Build <p> paragraph.""" | |
return Paragraph(build_text(content, font_size=font_size), NORM_STYLE) | |
def build_h1(content: str, font_size: int = 8): | |
"""Build <h1> paragraph.""" | |
return Paragraph(build_text(content, font_size=font_size), H1_STYLE) | |
def build_space(): | |
return Spacer(1, 12) | |
def main(): | |
"""Main logic of the program.""" | |
output = BytesIO() | |
doc = BaseDocTemplate( | |
output, | |
pagesize=letter, | |
rightMargin=72, | |
leftMargin=72, | |
topMargin=72, | |
bottomMargin=72, | |
) | |
# Define a page template | |
frame = Frame( | |
doc.leftMargin, doc.bottomMargin, doc.width, doc.height - 20, id="normal" | |
) | |
template = PageTemplate(id="tbase", frames=frame, onPage=context) | |
doc.addPageTemplates([template]) | |
# Generate content | |
Story = [] | |
for i in range(10): | |
Story.append(build_p(LOREM)) | |
Story.append(build_space()) | |
Story.append(build_p(HELLO_MULTI)) | |
Story.append(build_space()) | |
# Save file contents | |
doc.build(Story) | |
# Pass bytes into open file | |
with open("demo_doc.pdf", "wb") as f: | |
f.write(output.getvalue()) | |
if __name__ == "__main__": | |
main() |
Official links:
Codebase links:
Community links: