You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

生成含Pandas数据框的PDF并添加页码及代码优化咨询

优化Pandas数据框转PDF并添加页码的方案

你的现有代码存在几个可以改进的地方:重复的表格样式设置、多余的中间PDF文件、合并后添加页码的逻辑有错误。下面是重构后的完整方案,实现每页一个表格、自动添加右下角页码的需求:

核心优化点

  • 消除重复代码:把表格样式、CSV读取逻辑封装成函数,避免冗余
  • 直接生成单PDF文件:无需分文件再合并,Platypus会自动处理分页
  • 原生添加页码:通过ReportLab的页面回调函数,在生成PDF时直接插入页码,比水印方案更高效且原生

完整代码

import pandas as pd
import numpy as np
from reportlab.lib import colors
from reportlab.lib.pagesizes import letter, inch
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, PageBreak
from reportlab.pdfgen import canvas

# 封装表格样式函数,避免重复代码
def get_table_style():
    return 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),
    ])

# 读取CSV并转换为ReportLab Table对象(补上表头)
def csv_to_table(csv_path):
    df = pd.read_csv(csv_path).dropna()  # 处理缺失值
    table_data = np.array(df).tolist()
    # 原代码未包含表头,这里补上让表格更完整
    table_data.insert(0, df.columns.tolist())
    table = Table(table_data)
    table.setStyle(get_table_style())
    return table

# 定义页码绘制函数,放在每页右下角
def add_page_number(canvas, doc):
    page_num = canvas.getPageNumber()
    # 位置可按需调整:右边距1英寸,底部距0.5英寸
    canvas.drawRightString(
        doc.pagesize[0] - inch,
        0.5 * inch,
        f"Page {page_num}"
    )

# 主逻辑
if __name__ == "__main__":
    # 初始化PDF文档
    doc = SimpleDocTemplate("result.pdf", pagesize=letter)
    elements = []

    # 添加第一个表格(来自data1.csv)
    table1 = csv_to_table("data1.csv")
    elements.append(table1)
    # 强制分页,确保第二个表格在新页面
    elements.append(PageBreak())

    # 添加第二个表格(来自data2.csv)
    table2 = csv_to_table("data2.csv")
    elements.append(table2)

    # 生成PDF,指定页码回调函数
    doc.build(elements, onFirstPage=add_page_number, onLaterPages=add_page_number)

关键部分解释

  1. 代码复用get_table_style()csv_to_table()把重复逻辑抽离,后续新增表格只需调用函数,维护更方便
  2. 表头补充:原代码没有把DataFrame的表头加入表格,重构后补上让输出更符合报表需求
  3. 原生页码:通过onFirstPageonLaterPages参数,在PDF生成时直接绘制页码,比后加水印更稳定,不会出现图层叠加问题
  4. 分页控制PageBreak()确保每个表格单独占一页,满足你每页一个表格的需求

关于水印方案的说明

水印方案属于PDF后处理,需要先生成无页码的PDF再叠加页码,流程繁琐且容易出现显示异常。而我们用的原生回调方案是在生成PDF的过程中直接插入页码,无需中间文件,性能和可靠性都更好。

内容的提问来源于stack exchange,提问作者sam Adams

火山引擎 最新活动