Last active
December 20, 2023 13:38
-
-
Save nenodias/8c54500eb27884935d05b3ed3b0dd793 to your computer and use it in GitHub Desktop.
Reportlab example with header
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import pdb | |
from io import BytesIO | |
from reportlab.lib.pagesizes import letter, A4 | |
from reportlab.platypus import SimpleDocTemplate, Paragraph | |
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle | |
from reportlab.lib.enums import TA_CENTER | |
from reportlab.lib.units import inch | |
from reportlab.pdfgen import canvas | |
from reportlab.lib.units import mm | |
from reportlab.pdfbase.pdfmetrics import registerFont | |
from reportlab.pdfbase.ttfonts import TTFont | |
registerFont(TTFont('Arial','ARIAL.ttf')) | |
class MyPrint: | |
def __init__(self, buffer, pagesize): | |
self.buffer = buffer | |
if pagesize == 'A4': | |
self.pagesize = A4 | |
elif pagesize == 'Letter': | |
self.pagesize = letter | |
self.width, self.height = self.pagesize | |
@staticmethod | |
def _header_footer(canvas, doc): | |
# Save the state of our canvas so we can draw on it | |
canvas.saveState() | |
styles = getSampleStyleSheet() | |
# Header | |
header = Paragraph('This is a multi-line header. It goes on every page. ' * 5, styles['Normal']) | |
w, h = header.wrap(doc.width, doc.topMargin) | |
header.drawOn(canvas, doc.leftMargin, doc.height + doc.topMargin - h) | |
# Footer | |
footer = Paragraph('This is a multi-line footer. It goes on every page. ' * 5, styles['Normal']) | |
w, h = footer.wrap(doc.width, doc.bottomMargin) | |
footer.drawOn(canvas, doc.leftMargin, h) | |
# Release the canvas | |
canvas.restoreState() | |
def print_users(self): | |
buffer = self.buffer | |
doc = SimpleDocTemplate(buffer, | |
rightMargin=72, | |
leftMargin=72, | |
topMargin=72, | |
bottomMargin=72, | |
pagesize=self.pagesize) | |
# Our container for 'Flowable' objects | |
elements = [] | |
# A large collection of style sheets pre-made for us | |
styles = getSampleStyleSheet() | |
styles.add(ParagraphStyle(name='centered', alignment=TA_CENTER)) | |
# Draw things on the PDF. Here's where the PDF generation happens. | |
# See the ReportLab documentation for the full list of functionality. | |
users = [ | |
{'name':'Teste'}, | |
{'name':'Teste1'}, | |
{'name':'Teste2'} | |
] | |
elements.append(Paragraph('My User Names', styles['Heading1'])) | |
for i, user in enumerate(users): | |
elements.append(Paragraph(user['name'], styles['Normal'])) | |
doc.build(elements, onFirstPage=self._header_footer, onLaterPages=self._header_footer, | |
canvasmaker=NumberedCanvas) | |
# Get the value of the BytesIO buffer and write it to the response. | |
#pdf = buffer.getvalue() | |
#buffer.close() | |
#return pdf | |
''' | |
Usage with django | |
@staff_member_required | |
def print_users(request): | |
# Create the HttpResponse object with the appropriate PDF headers. | |
response = HttpResponse(content_type='application/pdf') | |
response['Content-Disposition'] = 'attachment; filename="My Users.pdf"' | |
buffer = BytesIO() | |
report = MyPrint(buffer, 'Letter') | |
pdf = report.print_users() | |
response.write(pdf) | |
return response | |
''' | |
class NumberedCanvas(canvas.Canvas): | |
def __init__(self, *args, **kwargs): | |
canvas.Canvas.__init__(self, *args, **kwargs) | |
self.Canvas = canvas.Canvas | |
self._saved_page_states = [] | |
def showPage(self): | |
self._saved_page_states.append(dict(self.__dict__)) | |
self._startPage() | |
def save(self): | |
"""add page info to each page (page x of y)""" | |
num_pages = len(self._saved_page_states) | |
for state in self._saved_page_states: | |
self.__dict__.update(state) | |
pdb.set_trace() | |
self.setFont('Arial', 8) | |
self.draw_page_number(num_pages) | |
self.Canvas.showPage(self) | |
self.Canvas.save(self) | |
def draw_page_number(self, page_count): | |
# Change the position of this to wherever you want the page number to be | |
self.drawRightString(211 * mm, 15 * mm + (0.2 * inch), | |
"Page %d of %d" % (self._pageNumber, page_count)) | |
if __name__ == '__main__': | |
buffer = BytesIO() | |
report = MyPrint(buffer, 'Letter') | |
pdf = report.print_users() | |
buffer.seek(0) | |
with open('arquivo.pdf', 'wb') as f: | |
f.write(buffer.read()) |
Very helpful example!
Do you have any idea how to generate a pdf with the data from a "POST" with django rest framework?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Your welcome, I haven't.