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

JSON转PDF表格自动换行问题求助:Python实现优化方案

解决JSON转PDF时表格内容溢出自动换行问题

问题根源

fpdf原生表格功能不支持自动换行,直接输出长文本会超出页面右侧边界;pandas转译后导入PDF也无法处理动态换行和行高调整。

优化实现代码

先准备示例JSON数据:

{
  "data": [
    {
      "id": 1,
      "title": "Python数据处理入门指南",
      "description": "这是一本详细介绍使用Pandas、NumPy等库进行数据清洗、转换、分析的入门书籍,涵盖了从基础数据结构到复杂数据分析项目的全流程内容"
    },
    {
      "id": 2,
      "title": "FPDF库高级使用技巧",
      "description": "深入讲解FPDF库的自定义样式、表格布局、分页处理以及特殊元素(如图片、二维码)的添加方法,帮助开发者生成更专业的PDF文档"
    }
  ]
}

以下是优化后的Python代码,实现文本自动换行、动态行高调整:

from fpdf import FPDF
import json

class PDF(FPDF):
    def __init__(self):
        super().__init__()
        self.set_margins(20, 20, 20)  # 设置页边距
        self.add_page()
        self.set_font("SimSun", size=12)  # 加载中文字体,需确保字体文件存在

    def text_wrap(self, text, max_width):
        # 拆分文本为适配指定宽度的多行
        lines = []
        current_line = ""
        for word in text.split():
            # 测试当前单词加入后是否超出宽度
            test_line = f"{current_line} {word}".strip()
            if self.get_string_width(test_line) <= max_width:
                current_line = test_line
            else:
                lines.append(current_line)
                current_line = word
        if current_line:
            lines.append(current_line)
        return lines

    def draw_table(self, headers, data, col_widths):
        # 绘制表头
        self.set_font("SimSun", 'B', 12)
        for i, header in enumerate(headers):
            self.cell(col_widths[i], 10, header, border=1, align='C')
        self.ln()

        # 绘制表格内容
        self.set_font("SimSun", size=12)
        for row in data:
            # 获取每个单元格的换行文本
            line_groups = []
            max_lines = 0
            for i, text in enumerate(row):
                lines = self.text_wrap(str(text), col_widths[i]-2)  # 留2单位内边距
                line_groups.append(lines)
                if len(lines) > max_lines:
                    max_lines = len(lines)
            
            # 按最大行数逐行绘制单元格
            for line_idx in range(max_lines):
                for col_idx in range(len(col_widths)):
                    text = line_groups[col_idx][line_idx] if line_idx < len(line_groups[col_idx]) else ""
                    self.cell(col_widths[col_idx], 10, text, border=1, align='L')
                self.ln()

# 加载JSON数据
with open("data.json", "r", encoding="utf-8") as f:
    json_data = json.load(f)

# 初始化PDF并绘制表格
pdf = PDF()
headers = ["ID", "标题", "描述"]
# 分配列宽:总可用宽度=页面宽度-左右边距=210-40=170
col_widths = [30, 50, 90]
data_rows = [[item["id"], item["title"], item["description"]] for item in json_data["data"]]
pdf.draw_table(headers, data_rows, col_widths)

pdf.output("output.pdf")

关键优化点说明

  • 文本换行处理:通过text_wrap函数逐词测试文本宽度,拆分出适配列宽的多行文本
  • 动态行高:根据单元格内的最大行数,逐行绘制每个单元格内容,确保行高足够容纳所有换行文本
  • 中文字体支持:加载SimSun等中文字体,避免中文乱码(需将字体文件放在可访问路径)
  • 列宽分配:根据页面可用宽度合理分配各列宽度,避免整体超出页面

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 07:57:30