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

Flutter Web下如何将HTML内容转为PDF?不支持flutter_html_to_pdf

Flutter Web 实现HTML转PDF方案

针对Flutter Web环境下无法使用flutter_html_to_pdf的问题,提供两种可行实现方式:

方法一:通过JS库(jsPDF + html2canvas)实现

利用浏览器原生JS能力,将HTML转为图片后生成PDF,适合复杂HTML内容,渲染效果与浏览器一致。

步骤1:引入JS库

将jspdf和html2canvas的本地文件放入web/js目录,然后在web/index.html中添加:

<script src="js/jspdf.umd.min.js"></script>
<script src="js/html2canvas.min.js"></script>

步骤2:编写Dart工具类

通过dart:js调用JS逻辑:

import 'dart:js' as js;

class HtmlToPdfConverter {
  static Future<void> generatePdf(String htmlContent) async {
    js.context.callMethod('eval', ['''
      // 创建临时容器存放HTML
      const tempContainer = document.createElement('div');
      tempContainer.innerHTML = `$htmlContent`;
      document.body.appendChild(tempContainer);

      // 将HTML转为画布再生成PDF
      html2canvas(tempContainer).then(canvas => {
        const pdf = new jspdf.jsPDF('p', 'mm', 'a4');
        const pageWidth = pdf.internal.pageSize.getWidth();
        const imgWidth = pageWidth;
        const imgHeight = (canvas.height * imgWidth) / canvas.width;

        let remainingHeight = imgHeight;
        let currentY = 0;

        // 添加第一页
        pdf.addImage(canvas.toDataURL('image/png'), 'PNG', 0, currentY, imgWidth, imgHeight);
        remainingHeight -= pdf.internal.pageSize.getHeight();

        // 处理分页
        while (remainingHeight >= 0) {
          currentY = remainingHeight - imgHeight;
          pdf.addPage();
          pdf.addImage(canvas.toDataURL('image/png'), 'PNG', 0, currentY, imgWidth, imgHeight);
          remainingHeight -= pdf.internal.pageSize.getHeight();
        }

        // 下载PDF并清理临时元素
        pdf.save('output.pdf');
        document.body.removeChild(tempContainer);
      });
    ''']);
  }
}

调用方式

final htmlContent = '<p>sample text</p><p><b>sample text</b></p><p><i><b>sample text</b></i><br></p>';
await HtmlToPdfConverter.generatePdf(htmlContent);

方法二:纯Dart实现(pdf + printing库)

通过解析HTML节点,手动构建PDF内容,适合结构简单的HTML,无需依赖JS。

步骤1:添加依赖

在pubspec.yaml中添加:

dependencies:
  pdf: ^3.10.0
  printing: ^6.2.0
  html: ^0.15.4

步骤2:编写转换逻辑

import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart' as pw;
import 'package:printing/printing.dart';
import 'package:html/parser.dart' as parser;
import 'package:html/dom.dart' as dom;

Future<void> convertHtmlToPdf(String html) async {
  final pdfDoc = pw.Document();
  final dom.Document htmlDoc = parser.parse(html);

  // 遍历HTML段落节点,转换为PDF文本组件
  for (final element in htmlDoc.body!.children) {
    if (element is dom.Element && element.localName == 'p') {
      final text = element.text;
      final hasBold = element.querySelector('b') != null;
      final hasItalic = element.querySelector('i') != null;

      pdfDoc.addPage(
        pw.Page(
          build: (context) => pw.Container(
            padding: pw.EdgeInsets.all(16),
            child: pw.Text(
              text,
              style: pw.TextStyle(
                fontWeight: hasBold ? pw.FontWeight.bold : pw.FontWeight.normal,
                fontStyle: hasItalic ? pw.FontStyle.italic : pw.FontStyle.normal,
                fontSize: 14,
              ),
            ),
          ),
        ),
      );
    }
  }

  // 导出PDF
  await Printing.sharePdf(bytes: await pdfDoc.save(), filename: 'output.pdf');
}

调用方式

final htmlContent = '<p>sample text</p><p><b>sample text</b></p><p><i><b>sample text</b></i><br></p>';
await convertHtmlToPdf(htmlContent);

两种方案对比

  • 方法一:渲染效果还原度高,支持复杂HTML(含样式、图片),但依赖浏览器JS环境。
  • 方法二:纯Dart跨平台,无需额外JS资源,但需要手动处理HTML节点,对复杂结构适配成本高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 13:35:01