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

Flutter开发APP:如何生成与指定样式匹配的自定义PDF?

Flutter生成自定义PDF的实现思路与方法

一、核心依赖选择

在Flutter中生成自定义PDF,优先选用以下两个维护成熟的包:

  • pdf:负责PDF文档的构建与布局渲染,支持用Flutter Widget语法编写PDF内容,降低学习成本
  • printing:提供PDF预览、保存、分享、打印等配套功能,和pdf包完美兼容

在pubspec.yaml中添加依赖:

dependencies:
  pdf: ^3.10.0
  printing: ^5.12.0

二、布局还原思路(匹配目标样式)

从你提供的PDF样式来看,包含标题、表格、多行文本、签名栏等元素,还原步骤如下:

  1. 页面基础配置
    设置PDF页面尺寸(默认A4)、边距,确保整体布局和目标样式对齐:
final doc = pw.Document();
doc.addPage(
  pw.Page(
    margin: const pw.EdgeInsets.all(16),
    build: (pw.Context context) {
      // 页面内容在此构建
    },
  ),
);
  1. 文本与标题处理
    用pw.Text组件设置不同字号、粗细,还原标题和正文的层级样式:
pw.Text("申请单", style: pw.TextStyle(fontSize: 20, fontWeight: pw.FontWeight.bold)),
pw.SizedBox(height: 10),
pw.Text("申请人:${formData['name']}", style: pw.TextStyle(fontSize: 14)),
  1. 表格布局实现
    目标样式中的表格部分,用pw.Table组件实现,配置边框、单元格对齐和内边距:
pw.Table(
  border: pw.TableBorder.all(width: 1),
  children: [
    pw.TableRow(
      children: [
        pw.Padding(padding: const pw.EdgeInsets.all(8), child: pw.Text("项目")),
        pw.Padding(padding: const pw.EdgeInsets.all(8), child: pw.Text("内容")),
      ],
    ),
    pw.TableRow(
      children: [
        pw.Padding(padding: const pw.EdgeInsets.all(8), child: pw.Text("申请事由")),
        pw.Padding(padding: const pw.EdgeInsets.all(8), child: pw.Text(formData['reason'])),
      ],
    ),
    // 补充更多表格行
  ],
),
  1. 自定义区块(如签名栏)
    签名栏用pw.Row组合文本和横线实现,控制对齐方式:
pw.Row(
  mainAxisAlignment: pw.MainAxisAlignment.end,
  children: [
    pw.Column(
      children: [
        pw.Text("申请人签名"),
        pw.SizedBox(height: 5),
        pw.Container(width: 120, height: 1, color: pw.Colors.black),
        pw.Text(formData['signName']),
      ],
    ),
  ],
),
  1. 中文字体适配
    默认字体不支持中文,需加载自定义字体(如思源黑体):
final font = await rootBundle.load("fonts/SourceHanSansCN-Normal.ttf");
final ttf = pw.Font.ttf(font);
// 在Text组件中指定字体
pw.Text("中文内容", style: pw.TextStyle(font: ttf)),

三、数据填充与生成流程

  1. 收集表单数据
    从应用内表单的TextEditingController、下拉选择框等组件中,将用户填写的数据整理为Map或实体类:
final formData = {
  'name': nameController.text,
  'reason': reasonController.text,
  'signName': signNameController.text,
  // 其他字段
};
  1. 构建PDF文档
    将收集到的数据填充到上述布局组件中,完成PDF文档的构建。

  2. 预览与导出
    用printing包实现PDF的预览、保存或分享:

  • 预览:
    PdfPreview(
      build: (context) => generatePdf(formData),
    );
    
  • 保存到本地:
    await Printing.layoutPdf(
      onLayout: (format) async => generatePdf(formData).save(),
    );
    
  • 分享PDF:
    await Printing.sharePdf(
      bytes: await generatePdf(formData).save(),
      filename: "申请单.pdf",
    );
    

四、细节优化建议

  • 测试不同设备的渲染效果,确保PDF样式跨平台一致
  • 长文本使用pw.Wrap或pw.Expanded组件避免内容溢出
  • 需要添加图片(如logo)时,用pw.Image加载本地资源或网络图片

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 21:40:30