how to know the end of a frame to create a new one reportlab

那年仲夏 提交于 2019-12-12 06:06:34

问题


I built a pdf using reportlab, to have more controle one the page (colors- padding- return to line...) I created a frame.

the issue is that, my text is coming from a database and it need more than one page.

I want to know how to tell that its the end of the page/frame and I should create a new one for the rest of text.

import MySQLdb
import pprint
import sys
import csv
from datetime import *
from reportlab.pdfgen import canvas
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib.pagesizes import landscape, letter, A4
from reportlab.lib.units import cm, inch
from reportlab.platypus import Image, Paragraph, Frame, KeepInFrame

styles = getSampleStyleSheet()
styleN = styles['Normal']
styleH = styles['Heading1']
story = []


pdf_file_name = 'report_.pdf'
c = canvas.Canvas(pdf_file_name)
f = Frame(0.5*inch, inch, 7*inch, 10.5*inch, showBoundary=1)

story.append(Paragraph("<font size='12' face='times' color='blue'>>SOME TEXT!</font>",styleN))
story.append(Paragraph("<font size='10' face='times'>SOME TEXT</font>", styleN) )
story.append( Paragraph('MORE TEXT HERE', styleN ) )

f.addFromList(story,c)
del story [:]
c.save()

回答1:


According to the reportlab API, you should not be using a Frame directly, rather you should be using a Flowable such as Paragraph instead and that will create and manipulate the Frames for you. For example, instead of f.addFromList(story,c) you ought to use

for p in story:
    while f.add(p, c) == 0:
        f.split(p, c)
        f = Frame(0.5*inch, inch, 7*inch, 10.5*inch, showBoundary=1)

This way, f.add will return 1 on success and 0 when it can't fit p into it, when that happens we use f.split to extract as much as possible from p to fill up f than replace f with a new Frame.




回答2:


I guess you could do it like this, though I'm not sure if it's the best way to do it.

If we start by declaring a string variable with the entire text from the database

the_text = "Here you would have your sql call, but this is just for demonstration purposes :)"

Our next move would be to create a list of all the words in

text_list = the_text.split(' ')

You might have to configure this just a bit, depending on how many words fit on one page. For this, I'm just going to say we want 3 words on each page.

words_on_page = 3

Now for the "magic". We make a for loop where x is going to itterate in steps trough the text_list And in this case it starts on the first word at 0 and jumps up 3 each loop

Then inside the loop we have a one liner that goes from x to (x + 3) And then for each 3 words we join them together with a whitespace.

And then you can put that into your frame

for x in range(0, len(text_list), words_on_page):
    page_text = " ".join(text_list[x:x + words_on_page])
    do_something_with_the(page_text)

And now we have lists of words fitting on to each page. Where each page has an eaqual amount of words on it. Which might not be ideal, but you can take this and make a better split.

The Code:

the_text = "Here you would have your sql call, but this is just for demonstration purposes :)"

text_list = the_text.split(' ')

words_on_page = 3

for x in range(0, len(text_list), words_on_page):
    page_text = " ".join(text_list[x:x + words_on_page])
    do_something_with_the(page_text)


来源:https://stackoverflow.com/questions/28778261/how-to-know-the-end-of-a-frame-to-create-a-new-one-reportlab

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!