Rotated document with ReportLab (vertical text)

I am trying to get something like the following snippet to draw this document rotated 90 degrees. In the end, this is the one I need, but the text is still horizontal. How can I rotate the text by making it vertical?

style = getSampleStyleSheet() normal = style["Normal"] normal.alignment = TA_CENTER normal.fontName = "Helvetica" normal.fontSize = 15 pdf = SimpleDocTemplate("testplatypus.pdf", pagesize = (80, 250), rightMargin=10, leftMargin=10, topMargin=20,bottomMargin=20) story = [] text = "I really need this to be wrapped and vertical!" para = Paragraph(text, normal) story.append(para) pdf.build(story) 
+6
source share
4 answers

This is Google’s best result on this, so I decided to post a better solution. My answer comes right from here

If you use a document template, you can use the very light Flowable, which will create vertical text in a specific cell in the table.

 # rotatedtext.py from reportlab.platypus.flowables import Flowable class verticalText(Flowable): '''Rotates a text in a table cell.''' def __init__(self, text): Flowable.__init__(self) self.text = text def draw(self): canvas = self.canv canvas.rotate(90) fs = canvas._fontsize canvas.translate(1, -fs/1.2) # canvas._leading? canvas.drawString(0, 0, self.text) def wrap(self, aW, aH): canv = self.canv fn, fs = canv._fontname, canv._fontsize return canv._leading, 1 + canv.stringWidth(self.text, fn, fs) 

Then use it in the document:

 # vertical_text_table.py from reportlab.pdfbase import pdfmetrics from reportlab.pdfbase.ttfonts import TTFont from reportlab.lib import colors from reportlab.lib.colors import HexColor from reportlab.lib.pagesizes import letter from reportlab.lib.styles import getSampleStyleSheet from reportlab.lib.units import inch from reportlab.platypus import ( BaseDocTemplate, Frame, Paragraph, NextPageTemplate, PageBreak, PageTemplate, Image, Table, TableStyle, Spacer) from rotatedtext import verticalText document = BaseDocTemplate( 'Vertical.pdf') Elements = [] titleFrame_1 = Frame( 0.5*inch, 0.75*inch, 7*inch, 9*inch, id='col1', showBoundary=0) titleTemplate_1 = PageTemplate( id='OneCol', frames=titleFrame_1) document.addPageTemplates([titleTemplate_1]) cw = [1.2*inch] + [1*inch]*6 rh = [0.25*inch] + [.6*inch] + [0.25*inch]*7 data = [ ['Some', 'Reporting', '', 'Data', '', 'Here', ''], ['', verticalText('Vertical'), verticalText('Text'), verticalText('Vertical'), verticalText('Text'), verticalText('Vertical'), verticalText('Text')], ['Row1', '0', '0', '69', '803', '20751', '11627'], ['Row2', '0', '0', '1', '0', '1096', '103'], ['Row3', '0', '0', '0', '0', '233', '1'], ['Row4', '0', '0', '0', '0', '694', '38'], ['Row5', '0', '0', '23', '2', '1319', '2'], ['Row6', '0', '0', '0', '0', '0', '0'], ['TOTAL', '0', '0', '93', '805', '24093', '11771'], ] ts = [ ('GRID', (0, 0), (-1, -1), 0.5, colors.black), ('SPAN', (1, 0), (2, 0)), ('SPAN', (3, 0), (4, 0)), ('SPAN', (5, 0), (6, 0)), ('SPAN', (0, 0), (0, 1)), ('ALIGN', (0, 0), (-1, 1), 'CENTER'), ('ALIGN', (0, 2), (-1, -1), 'RIGHT'), ('VALIGN', (0, 0), (-1, -2), 'MIDDLE'), ('FONT', (0, 0), (-1, 1), 'Helvetica-Bold', 7, 7), ('FONT', (0, 2), (0, -2), 'Helvetica-Bold', 7, 7), ('FONT', (1, 2), (-1, -2), 'Helvetica', 7, 7), ('FONT', (0, -1), (-1, -1), 'Helvetica-Bold', 8, 8), ('TEXTCOLOR', (0, -1), (-1, -1), colors.white), ('BACKGROUND', (0, -1), (-1, -1), colors.black), ] t = Table( data, style=ts, colWidths=cw, rowHeights=rh) Elements.append(t) document.build(Elements) 

Which gives:

Table with vertical text.

+5
source

Perhaps you can do this by adding build methods.

It is something like this.

 pdf = SimpleDocTemplate("testplatypus.pdf", pagesize = (80, 250), rightMargin=10, leftMargin=10, topMargin=20,bottomMargin=20) pdf.build(Story, onFirstPage = myFirstPage, onLaterPages=myLaterPages) def myFirstPage(canvas, doc): canvas.saveState() canvas.rotate(90) canvas.restoreState() def myLaterPages(canvas, doc): canvas.saveState() canvas.rotate(90) canvas.restoreState() 
+1
source

I found an easy way around this USING canvas.drawString (). This is in a regular Python function. The “WHATEVER TEXT” in the example below will be the RENDER TEXT verdict on your PDF. Read the comments in the code to fully understand how to achieve this.

 def lista_privados(request, pk): g1 = get_object_or_404(Grupo, pk=pk) response = HttpResponse(content_type='application/pdf') response['Content-Disposition'] = 'attachment; filename="{}"'.format(g1) buffer = BytesIO() c = canvas.Canvas(buffer, pagesize=A4) c.setPageSize(landscape(letter)) #Whatever your other code is 

It’s important that this only works at the very end, until your showPage ()

  c.rotate(90) c.drawString(16*cm, -14*cm, "WHATEVER TEXT 1") c.drawString(16*cm, -14.4*cm, "WHATEVER TEXT 2") #c.drawString(x*cm, y*cm, "TEXT YOU WANT TO DISPLAY VERICALLY") #Note the '-' is VERY IMPORTANT OR IT WON'T WORK #ONLY WRITE THE c.rotate(90) one, you can list as many 'c.drawString(16*cm, -14*cm, "WHATEVER TEXT")' as you wish #The font size will be the last one you set on your code, so if for example you do "c.setFont('Helvetica', 5)" just the "c.rotate(90)", "WHATEVER TEXT" will be Helvetica, 5. c.showPage() #save page c.save() pdf = buffer.getvalue() buffer.close() response.write(pdf) template = 'privados/imp_list.html' return response 
0
source

If you want to convert horizontal text to vertical text, I found a simple straight path.

 def your_function_name(request, pk): g1 = get_object_or_404(Grupo, pk=pk) response = HttpResponse(content_type='application/pdf') response['Content-Disposition'] = 'attachment; filename=Plista2.pdf' buffer = BytesIO() c = canvas.Canvas(buffer, pagesize=A4) c.setPageSize(landscape(letter)) 
-1
source

Source: https://habr.com/ru/post/1441963/


All Articles