You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python 3.9基于DataFrame/数据库数据生成账单样式PDF的方法

Python 基于结构化数据生成账单类PDF实现方案

适用环境:Python 3.9,可直接集成到你现有从SQLite取数生成JSON的代码逻辑中,无重型依赖,生成的PDF满足邮件发送、存档、纸质打印的账单需求。

前置依赖安装

执行以下命令安装需要的库:

pip install pandas reportlab
  • pandas:用于结构化数据的快速处理、金额统计,如果你已经有处理好的DataFrame可以直接使用
  • reportlab:轻量PDF生成库,支持自定义表格、文本样式,不需要依赖外部浏览器或报表服务

可直接复用的实现代码

1. 通用PDF账单生成函数

这个函数接收你已经整理好的键值对格式销售数据,自动生成带抬头、客户信息、明细表格、合计金额的标准样式账单:

import sqlite3
import json
import collections
import pandas as pd
from reportlab.lib import colors
from reportlab.lib.pagesizes import A4
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph, Spacer
from reportlab.lib.styles import getSampleStyleSheet


def generate_bill_pdf(sales_data: list, customer_name: str, output_path: str = None):
    """
    生成客户消费账单PDF
    :param sales_data: 键值对格式的销售明细列表,和你现有objects_list结构一致
    :param customer_name: 客户姓名
    :param output_path: PDF输出路径,默认以客户名命名
    """
    if not output_path:
        output_path = f"{customer_name}_消费账单.pdf"
    
    # 初始化A4尺寸PDF文档
    doc = SimpleDocTemplate(output_path, pagesize=A4)
    styles = getSampleStyleSheet()
    content_list = []

    # 添加账单抬头
    title = Paragraph("<b>消费账单</b>", styles["Title"])
    content_list.append(title)
    content_list.append(Spacer(1, 20))

    # 添加客户信息
    customer_tag = Paragraph(f"客户姓名:{customer_name}", styles["Normal"])
    content_list.append(customer_tag)
    content_list.append(Spacer(1, 20))

    # 数据转DataFrame做统计
    df = pd.DataFrame(sales_data)
    # 计算消费总金额
    total = (df["Quantity"] * df["Price"]).sum()
    # 组装表格数据:第一行为表头,后续为明细,最后加合计行
    table_content = [df.columns.tolist()] + df.values.tolist()
    table_content.append(["", "", "", "总金额", round(total, 2)])

    # 设置表格样式
    bill_table = Table(table_content)
    table_style = TableStyle([
        # 表头样式
        ("BACKGROUND", (0, 0), (-1, 0), colors.darkblue),
        ("TEXTCOLOR", (0, 0), (-1, 0), colors.white),
        ("FONTNAME", (0, 0), (-1, 0), "Helvetica-Bold"),
        ("ALIGN", (0, 0), (-1, 0), "CENTER"),
        ("BOTTOMPADDING", (0, 0), (-1, 0), 10),
        # 明细行样式
        ("ALIGN", (0, 1), (-1, -2), "CENTER"),
        ("GRID", (0, 0), (-1, -1), 0.5, colors.black),
        ("ROWBACKGROUNDS", (0, 1), (-1, -2), [colors.white, colors.lightblue]),
        # 合计行样式
        ("BACKGROUND", (0, -1), (-1, -1), colors.lightgrey),
        ("FONTNAME", (0, -1), (-1, -1), "Helvetica-Bold"),
        ("ALIGN", (0, -1), (-1, -1), "CENTER"),
    ])
    bill_table.setStyle(table_style)
    content_list.append(bill_table)

    # 生成最终PDF
    doc.build(content_list)

2. 修改你现有的bill_gen函数

在原有生成JSON的逻辑后直接调用PDF生成函数即可,代码里标注了原有逻辑的两个可修复问题:

def bill_gen(c_name):
    user_name = c_name.get()
    connection_create()
    cursor = sqliteConnection.cursor()
    
    # 注意:原SQL用字符串格式化拼接存在注入风险,建议替换为参数化查询
    # cursor.execute("select * from sales where customer_name= ?", (user_name,))
    cursor.execute("select * from sales where customer_name= '{}'".format(user_name))
    result = cursor.fetchall()
    print(result, type(result))
    connection_close()

    rowarray_list = []
    for rows in result:
        t = (rows[0], rows[1], rows[2], rows[3], rows[4])
        rowarray_list.append(t) 
    # 注意:原代码此处dump的是循环最后一个rows变量,会导致bill.js只存最后一条数据,已修正
    j = json.dumps(rowarray_list)
    with open("bill.js", "w") as f:
        f.write(j)

    # 转换为键值对格式
    objects_list = []
    for row in result:
        d = collections.OrderedDict()
        d["id"] = row[0]
        d["Customer Name"] = row[1]
        d["Medicines"] = row[2]
        d["Quantity"] = row[3]
        d["Price"] = row[4]
        objects_list.append(d)
    j = json.dumps(objects_list)
    with open("bill_objects.js", "w") as f:
        f.write(j)

    # 新增:生成PDF账单
    generate_bill_pdf(objects_list, user_name)

补充说明

  • 生成的PDF默认带斑马纹表格、清晰的表头和合计行,不需要额外调整就能满足普通账单的展示需求,文件体积小,适合邮件发送和云端存储
  • 如果你已经有处理完成的DataFrame,不需要走JSON转换逻辑,直接将df.columns.tolist() + df.values.tolist()作为表格内容传入即可
  • 如需自定义样式(比如添加公司logo、修改字体、增加账单备注、开票信息栏),直接在generate_bill_pdf的content_list中添加对应元素即可,不需要更换其他重型报表工具
  • 如果需要读取已经生成的bill_objects.js文件生成PDF,直接用json.load读取文件内容得到objects_list,再传给生成函数即可

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 01:36:21