我正在尝试自动化构建包含熊猫数据框的PDF的过程。但是,我想在页面的右下角添加页码。我还想知道我是否可以改进现有代码。
到目前为止,我已经编写了一个脚本,该脚本使用两个熊猫数据帧,将它们放在单独的pdf中,然后将它们合并在一起以创建最终的pdf。
from reportlab.pdfgen import canvas
from reportlab.platypus import SimpleDocTemplate
from reportlab.pdfgen import canvas
from reportlab.platypus import *
from reportlab.lib import colors
from reportlab.lib.pagesizes import letter
import pandas as pd
import io
import numpy as np
from reportlab.lib import colors
from reportlab.lib.pagesizes import letter, inch
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle
data = pd.read_csv('data1.csv').dropna()
colwidths = 50
GRID_STYLE = TableStyle(
[('GRID', (0, 0), (-1, -1), 0.25, colors.black),
('ALIGN', (1, 0), (-1, -1), 'RIGHT')])
t1 = Table(np.array(data).tolist());
doc = SimpleDocTemplate("report1.pdf", pagesize=letter)
element = []
t1.setStyle(TableStyle([('ALIGN',(1,1),(-2,-2),'RIGHT'),
('TEXTCOLOR',(1,1),(-2,-2),colors.black),
('VALIGN',(0,0),(0,-1),'TOP'),
('TEXTCOLOR',(0,0),(0,-1),colors.black),
#('ALIGN',(0,-1),(-1,-1),'CENTER'),
#('VALIGN',(0,-1),(-1,-1),'MIDDLE'),
('TEXTCOLOR',(0,-1),(-1,-1),colors.black),
('INNERGRID', (0,0), (-1,-1), 0.25, colors.black),
('BOX', (0,0), (-1,-1), 0.25, colors.black),
]))
element.append(t1)
doc.build(element)
data2 = pd.read_csv('data2.csv')
t2 = Table(np.array(data2).tolist());
doc = SimpleDocTemplate("report2.pdf", pagesize=letter)
element2 = []
t2.setStyle(TableStyle([('ALIGN',(1,1),(-2,-2),'RIGHT'),
('TEXTCOLOR',(1,1),(-2,-2),colors.black),
('VALIGN',(0,0),(0,-1),'TOP'),
('TEXTCOLOR',(0,0),(0,-1),colors.black),
#('ALIGN',(0,-1),(-1,-1),'CENTER'),
#('VALIGN',(0,-1),(-1,-1),'MIDDLE'),
('TEXTCOLOR',(0,-1),(-1,-1),colors.black),
('INNERGRID', (0,0), (-1,-1), 0.25, colors.black),
('BOX', (0,0), (-1,-1), 0.25, colors.black),
]))
element.append(t2)
doc.build(element)
from PyPDF2 import PdfFileMerger, PdfFileReader
pdfs = ['report1.pdf', 'report2.pdf']
merger = PdfFileMerger()
for file in pdfs:
merger.append(file)
pdf = merger.write('result.pdf')
for page in range(pdf.getNumPages()):
pdf_page = pdf.getPage(page)
pdf_page.mergepage(watermark_page)
merger.addBookmark(pagenum)
merger.close()
我目前没有任何错误消息。我希望每页有一张表,并且有一个脚本能够创建PDF文件,该PDF的页数与我收到的表一样多,此数字可能会有所不同。所有页面都必须在页面的右下角具有页码。
我已经看到尝试使用水印进行此操作的方法,但是我不理解它,因此不确定在这里是否有用。
答案 0 :(得分:0)
此答案完全受此博客帖子-http://www.blog.pythonlibrary.org/2013/08/12/reportlab-how-to-add-page-numbers/
的启发我不完全了解这些内部函数的工作原理,但是基本思想是修改canvas.Canvas
的一些内部函数,以便将页码自动添加到生成的每个页面中。
首先,创建canvas.Canvas
类的子类来修改内部函数,如下所示,
from reportlab.lib import colors
from reportlab.lib.pagesizes import letter
from reportlab.lib.units import mm
from reportlab.pdfgen import canvas
from reportlab.platypus import PageBreak, SimpleDocTemplate, Table, TableStyle
import numpy as np
import pandas as pd
# Custom Canvas class for automatically adding page-numbers
class MyCanvas(canvas.Canvas):
def __init__(self, *args, **kwargs):
canvas.Canvas.__init__(self, *args, **kwargs)
self.pages = []
def showPage(self):
self.pages.append(dict(self.__dict__))
self._startPage()
def draw_page_number(self, page_count):
# Modify the content and styles according to the requirement
page = "{curr_page} of {total_pages}".format(curr_page=self._pageNumber, total_pages=page_count)
self.setFont("Helvetica", 10)
self.drawRightString(195*mm, 272*mm, page)
def save(self):
# Modify the save() function to add page-number before saving every page
page_count = len(self.pages)
for page in self.pages:
self.__dict__.update(page)
self.draw_page_number(page_count)
canvas.Canvas.showPage(self)
canvas.Canvas.save(self)
现在生成PDF。就您而言,
TABLE_STYLE = TableStyle([('ALIGN',(1,1),(-2,-2),'RIGHT'),
('TEXTCOLOR',(1,1),(-2,-2),colors.black),
('VALIGN',(0,0),(0,-1),'TOP'),
('TEXTCOLOR',(0,0),(0,-1),colors.black),
('TEXTCOLOR',(0,-1),(-1,-1),colors.black),
('INNERGRID', (0,0), (-1,-1), 0.25, colors.black),
('BOX', (0,0), (-1,-1), 0.25, colors.black),
])
content = list()
# This should be refactored into a for-loop
data_one = pd.read_csv('data1.csv').dropna()
t1 = Table(np.array(data_one).tolist())
t1.setStyle(TABLE_STYLE)
content.append(t1)
content.append(PageBreak())
data_two = pd.read_csv('data2.csv').dropna()
t2 = Table(np.array(data_two).tolist())
t2.setStyle(TABLE_STYLE)
content.append(t2)
content.append(PageBreak())
# Now generate the PDF at once with page numbers
doc = SimpleDocTemplate("result.pdf", pagesize=letter)
doc.build(content, canvasmaker=MyCanvas)
我已经通过生成一个虚拟PDF进行了测试,并且效果很好。希望这会有所帮助。