如何在 PDF 的底部(页脚)添加多行?
How to add multiple lines at bottom (footer) of PDF?
我必须创建 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
现在,如果文本有多行,那么这将不起作用,因为文本的长度大于页面大小的宽度。明白了。
我尝试使用 Frame
和 paragraph
但仍然无法在 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 link
首先是关于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()
假设您希望页脚跨越可写区域的宽度
注意:默认设置的页边距很大,这就是为什么边上有这么多空白 space。
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
)或在调用 [=18] 之后调用 P.height
来获取页脚的高度=].
通过在页脚的高度开始我们的 Frame
,我们将永远不会有重叠的文本。但重要的是要记住将 Frame
的高度设置为 doc.height - footer.height
以确保文本不会放置在页面之外。
我必须创建 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
现在,如果文本有多行,那么这将不起作用,因为文本的长度大于页面大小的宽度。明白了。
我尝试使用 Frame
和 paragraph
但仍然无法在 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 link
首先是关于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()
假设您希望页脚跨越可写区域的宽度
注意:默认设置的页边距很大,这就是为什么边上有这么多空白 space。
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
)或在调用 [=18] 之后调用 P.height
来获取页脚的高度=].
通过在页脚的高度开始我们的 Frame
,我们将永远不会有重叠的文本。但重要的是要记住将 Frame
的高度设置为 doc.height - footer.height
以确保文本不会放置在页面之外。