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

使用Pandas与ReportLab在Python中导出SQLite表至PDF的异常问题

解决Pandas+ReportLab导出SQLite数据到PDF仅显示表头的问题

我来帮你搞定这个问题!你遇到的核心问题是对Pandas DataFrame的迭代逻辑理解有误,加上ReportLab的绘制方式没对齐列,才导致PDF只显示表头且格式混乱。咱们一步步来修正:

问题根源分析

  • 当你直接写for row in rows时,Pandas的DataFrame默认迭代的是列名称,而不是表格的每一行数据——这就是为什么你只看到表头的原因。
  • 另外,你只用了一个固定的x坐标70来绘制所有内容,所有数据都会挤在同一列,自然格式不对。

修正后的完整代码

import sqlite3
import pandas as pd
from reportlab.lib.colors import black
from reportlab.pdfgen import canvas
from tkinter import Frame, Label, Button, Tk

class Example(Frame):
    def __init__(self, parent):
        Frame.__init__(self, parent)
        self.parent = parent
        self.initUI()

    def initUI(self):
        self.parent.title("Pdf_test")
        self.grid()
        self.label = Label(self.parent, text='Pdf test')
        self.label.grid(row=0, column=0)
        self.button = Button(self.parent, width=15, text=" PDF ", command=self.pdf_test)
        self.button.grid(row=1, column=0)

    def pdf_test(self):
        # 1. 数据库操作:用完后记得关闭连接,避免资源泄漏
        conn = sqlite3.connect("Baza_Date.db")
        try:
            # 读取SQLite表到DataFrame
            rows = pd.read_sql_query("SELECT * FROM test1", conn)
            print(rows)

            # 2. 初始化PDF画布
            report = canvas.Canvas("Multi.pdf")
            report.setFont("Times-Roman", 20)
            report.setFillColor(black)
            report.drawString(70, 750, "Test1 Table Data")  # 添加标题

            # 3. 配置表格样式:列宽、起始坐标、字体大小
            col_x = [70, 150, 230, 310]  # 根据你的列数调整每个列的x起始位置
            row_y = 720
            header_size = 12
            content_size = 9

            # 4. 绘制表头
            report.setFont("Helvetica-Bold", header_size)
            for idx, col_name in enumerate(rows.columns):
                report.drawString(col_x[idx], row_y, str(col_name))
            row_y -= 15  # 表头和内容之间留间距

            # 5. 绘制表格内容:用itertuples遍历每一行数据
            report.setFont("Helvetica", content_size)
            for row in rows.itertuples(index=False):  # index=False去掉默认的行索引
                # 遍历当前行的每个字段,对应列的x坐标绘制
                for idx, value in enumerate(row):
                    report.drawString(col_x[idx], row_y, str(value))
                row_y -= 12

                # 可选:处理分页,如果y坐标低于页边距,新建一页
                if row_y < 50:
                    report.showPage()
                    row_y = 750  # 重置y坐标到新页面顶部

            # 6. 保存PDF并关闭资源
            report.save()
        finally:
            conn.close()  # 确保数据库连接被关闭

if __name__ == "__main__":
    root = Tk()
    app = Example(root)
    root.mainloop()

关键改动说明

  1. 正确遍历DataFrame行:使用rows.itertuples(index=False)来获取每一行的实际数据,而不是列名。
  2. 列对齐排版:定义col_x列表来控制每一列的起始x坐标,让表头和内容一一对应,解决格式混乱问题。
  3. 资源管理:用try...finally确保数据库连接被关闭,避免资源泄漏。
  4. 分页处理:添加了简单的分页逻辑,当数据太多超出一页时自动新建页面。
  5. 样式优化:给表头用加粗字体,添加标题,调整行间距让内容更清晰。

现在你运行代码后,应该能看到完整的表格数据正确显示在PDF里了!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:04:26