ReportLab: How to auto resize text to fit block

2019-04-28 13:58发布

问题:

I need to generate a PDF with dynamic text and I'm using ReportLab. Since the text is dynamic, is there anyway to have it resized to fit within a specific area of the PDF?

回答1:

Starting in reportlab version 2.0 platypus has KeepInFrame. From the CHANGES.txt:

KeepInFrame:
Sometimes the length of a piece of text you'd like to include in a 
fixed piece of page "real estate" is not guaranteed to be constrained to a 
fixed maximum length. In these cases, KeepInFrame allows you to specify an 
appropriate action to take when the text is too long for the space allocated 
for it. In particular, it can shrink the text to fit, mask (truncate) 
overflowing text, allow the text to overflow into the rest of the document, or 
raise an error.

The only examples I could find on how to use it are in the reportlab source code in the tests/. Here is the working example I finally came up with:

from reportlab.pdfgen.canvas import Canvas
from reportlab.lib.pagesizes import letter, landscape
from reportlab.platypus import Paragraph, Frame, KeepInFrame
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib.units import inch

c = Canvas('foo.pdf', pagesize=landscape(letter))
frame1 = Frame(0.25*inch, 0.25*inch, 4*inch, 4*inch, showBoundary=1)

styles = getSampleStyleSheet()
s = "foo bar " * 1000
story = [Paragraph(s, styles['Normal'])]
story_inframe = KeepInFrame(4*inch, 8*inch, story)
frame1.addFromList([story_inframe], c)
c.save()

And the version string for completeness:

>python -c "import reportlab;print reportlab.Version"
2.7


回答2:

Yes. Take a look at the ReportLab manual. Based on your (short) description of what you want to do it sounds like you need to look at using Frames within your page layout (assuming you use Platypus, which I would highly recommend).