【问题标题】:How to add multiple lines at bottom (footer) of PDF?如何在 PDF 的底部(页脚)添加多行?
【发布时间】:2016-01-29 10:29:45
【问题描述】:

我必须创建 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

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

【问题讨论】:

    标签: python pdf reportlab


    【解决方案1】:

    首先是关于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.wraph)或在调用P.wrap 后调用P.height 来获取页脚的高度。

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

    【讨论】:

    • 好的,我会检查并通知您。我是按帧做的。这是工作。但是如果有 5 行,如何找到起始位置是我现在的问题。
    • Paragraph 的起始位置在报告实验室中始终位于左下方。当您添加更多行时,Paragraph 将开始垂直增长,但仍附着在左下角。如果您需要知道右上角,您可以使用P.height 结合本例中的起始位置 10。
    • @VivekSable 搞定了吗?如果您愿意,我可以将其添加到答案中。
    • 当然,您可以添加回答。我也会试试。 :)
    • 谢谢它正在工作,我会再次询问是否有问题。 :) 再次伟大的工作
    猜你喜欢
    • 2018-01-30
    • 2015-05-11
    • 2013-11-18
    • 1970-01-01
    • 1970-01-01
    • 2021-03-15
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多