如何在PDF底部(页脚)添加多行?

8

我需要创建一个PDF文件,在底部左侧添加像页脚一样的线。

以下代码可以工作:

import StringIO
from reportlab.pdfgen import canvas
import uuid

def test(pdf_file_name="abc.pdf", pdf_size=(432, 648), font_details=("Times-Roman", 9)):
    # create a new PDF with Reportla 
    text_to_add = "I am writing here.."
    new_pdf = "test_%s.pdf"%(str(uuid.uuid4()))

    packet = StringIO.StringIO() 
    packet.seek(0)

    c = canvas.Canvas(pdf_file_name, pagesize = pdf_size)
    #- Get the length of text in a PDF. 
    text_len = c.stringWidth(text_to_add, font_details[0], font_details[1])
    #- take margin 20 and 20 in both axis 
    #- Adjust starting point on x axis according to  text_len
    x = pdf_size[0]-20  -  text_len
    y = 20 
    #- set font.
    c.setFont(font_details[0], font_details[1])
    #- write text,
    c.drawString(x, y, text_to_add)

    c.showPage()
    c.save()
    return pdf_file_name

如果文本有多行,则此方法无法工作,因为文本的长度大于页面大小的宽度。已经理解。

我尝试使用Frameparagraph,但仍然无法将文本写在PDF的正确位置

以下是代码:

from reportlab.lib.pagesizes import letter
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.platypus import BaseDocTemplate, Frame, PageTemplate, Paragraph

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

def footer(canvas, doc):
    canvas.saveState()
    P = Paragraph("This is a multi-line footer.  It goes on every page.  " * 10, styleN)
    w, h = P.wrap(doc.width, doc.bottomMargin)
    print "w, h:", w, h
    print "doc.leftMargin:", doc.leftMargin
    P.drawOn(canvas, 10, 30)
    canvas.restoreState()

def test():
    doc = BaseDocTemplate('test.pdf', pagesize=(432, 648))
    print "doc.leftMargin:", doc.leftMargin
    print "doc.bottomMargin:", doc.bottomMargin
    print "doc.width:", doc.width  
    print "doc.height:", doc.height
    frame = Frame(10, 50, 432, 648, id='normal')
    template = PageTemplate(id='test', frames=frame, onPage=footer)
    doc.addPageTemplates([template])

    text = []
    for i in range(1):
        text.append(Paragraph("", styleN))

    doc.build(text) 

我不明白为什么页面的大小会发生变化,因为我设置了 (432, 648),但显示的是 (288.0, 504.0)

doc.leftMargin: 72.0
doc.bottomMargin: 72.0
doc.width: 288.0
doc.height: 504.0

此外,还有帧大小:

w, h: 288.0 96
doc.leftMargin: 72.0

不知道如何解决这个问题。 我参考了这个链接。

1个回答

6

首先解释关于doc.width的神秘问题,doc.width并不是文档实际宽度,而是页边距之间的宽度。所以在这种情况下,doc.width + doc.leftMargin + doc.rightMargin 等于实际页面的宽度。

现在回到为什么页脚没有像你想要的那样覆盖整个页面的问题。这是由于与上述相同的问题,即doc.width并不是实际纸张的宽度。

假设你想让页脚覆盖整个页面

def footer(canvas, doc):
    canvas.saveState()

    P = Paragraph("This is a multi-line footer.  It goes on every page.  " * 10, styleN)

    # Notice the letter[0] which is the width of the letter page size
    w, h = P.wrap(letter[0] - 20, doc.bottomMargin)

    P.drawOn(canvas, 10, 10)
    canvas.restoreState()

假设您希望页脚跨越可写区域的宽度。
注意:默认设置的边距相当大,所以两侧有很多空白区域。
def footer(canvas, doc):
    canvas.saveState()
    P = Paragraph("This is a multi-line footer.  It goes on every page.  " * 10, styleN)
    w, h = P.wrap(doc.width, doc.bottomMargin)
    print "w, h:", w, h
    print "doc.leftMargin:", doc.leftMargin
    P.drawOn(canvas, doc.leftMargin, 10)
    canvas.restoreState()

编辑:

为了知道正常文本从哪里开始,我们需要确定页脚的高度。在正常情况下,我们不能使用P.height,因为它取决于文本的宽度,调用它会引发AttributeError

在我们的情况下,我们实际上可以直接从P.wrap中获取页脚的高度(即h),或者在调用P.wrap之后调用P.height来获取页脚的高度。

通过在页面底部的页脚高度处开始我们的Frame,我们永远不会有重叠的文本。但是重要的是要记住将Frame的高度设置为doc.height - footer.height,以确保文本不会被放置在页面外部。


好的,我会检查并让您知道。我已经用框架做了,它可以工作。但是如果有5行,如何找到起始位置现在是我的问题。 - Vivek Sable
Paragraph 的起始位置始终位于 ReportLab 中的左下角。当您添加更多行时,Paragraph 将开始垂直增长,但仍保持附加在左下角。如果您需要知道右上角的位置,则可以将 P.height 与此情况下的起始位置(10)结合使用。 - B8vrede
将其添加到答案,并附上重要说明,即Frame的高度很容易被忘记。 - B8vrede
1
谢谢,它正常工作了,如果有问题我会再问的。:) 再次做得很好 - Vivek Sable
如何在上述情况下将RGB颜色和透明度设置为文本? - Vivek Sable
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接