Flutter中HTML转PDF或跳转至浏览器的实现方法
Flutter HTML转PDF及跳转浏览器实现方案(Android/PC平台)
注意:你当前使用的flutter_widget_from_html_core不支持JavaScript,所以HTML中的onclick事件无法触发,若需要打印/导出功能,建议通过Flutter端的逻辑实现。
一、HTML转PDF的实用库
1. printing + pdf 组合
这是Flutter里比较成熟的方案,支持Android和桌面平台,能较好保留HTML样式,还支持自定义PDF配置(如页边距、页眉页脚)。
步骤:
- 在
pubspec.yaml添加依赖:
dependencies: printing: ^5.12.0 pdf: ^3.10.0 flutter_widget_from_html_core: ^0.15.0 # 你已使用的库
- 修改代码添加导出PDF功能:
import 'package:flutter/material.dart'; import 'package:flutter_widget_from_html_core/flutter_widget_from_html_core.dart'; import 'package:printing/printing.dart'; import 'package:pdf/pdf.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), useMaterial3: true, ), home: const MyHomePage(title: 'Flutter Demo Home Page'), ); } } class MyHomePage extends StatefulWidget { const MyHomePage({super.key, required this.title}); final String title; @override State<MyHomePage> createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { String stringHtml = """ <html> <body> <h1>Hello, World!</h1></br> <h2>sub Hello World</h2> <button onclick="window.print()">Esse Botão Vai imprimir</button> </body> </html> """; // 导出HTML为PDF Future<void> _exportHtmlToPdf() async { try { final pdf = await Printing.convertHtml( format: PdfPageFormat.a4, html: stringHtml, ); await Printing.sharePdf(bytes: pdf, filename: 'my_document.pdf'); } catch (e) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('导出失败: $e')), ); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text(widget.title)), body: SingleChildScrollView( child: Column(children: [HtmlWidget(stringHtml)]), ), floatingActionButton: FloatingActionButton( onPressed: _exportHtmlToPdf, tooltip: '导出PDF', child: const Icon(Icons.picture_as_pdf), ), ); } }
2. flutter_html_to_pdf
这个库更轻量化,专注于HTML转PDF的核心需求,配置简单,适合快速集成。
步骤:
- 添加依赖:
dependencies: flutter_html_to_pdf: ^0.1.1 path_provider: ^2.1.1 printing: ^5.12.0 # 用于分享PDF
- 实现导出功能:
import 'package:flutter_html_to_pdf/flutter_html_to_pdf.dart'; import 'package:path_provider/path_provider.dart'; import 'package:printing/printing.dart'; // ... 保留原有类代码 ... Future<void> _exportHtmlToPdf() async { final outputDirectory = await getTemporaryDirectory(); final generatedPdfFile = await FlutterHtmlToPdf.convertFromHtmlContent( stringHtml, outputDirectory.path, "output", ); await Printing.sharePdf( bytes: generatedPdfFile.readAsBytesSync(), filename: 'output.pdf' ); }
二、将HTML跳转至系统浏览器的方案
使用url_launcher库,支持Android和桌面平台,可将HTML保存为本地临时文件后调用系统浏览器打开。
步骤:
- 添加依赖:
dependencies: url_launcher: ^6.2.5 path_provider: ^2.1.1
- 实现跳转功能:
import 'package:url_launcher/url_launcher.dart'; import 'package:path_provider/path_provider.dart'; import 'dart:io'; // ... 保留原有类代码 ... Future<void> _openHtmlInBrowser() async { // 将HTML写入临时文件 final tempDir = await getTemporaryDirectory(); final htmlFile = File("${tempDir.path}/document.html"); await htmlFile.writeAsString(stringHtml); final fileUri = htmlFile.absolute.uri.toString(); if (await canLaunchUrl(Uri.parse(fileUri))) { await launchUrl(Uri.parse(fileUri)); } else { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('无法打开浏览器')), ); } } // 修改build方法添加双按钮 @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text(widget.title)), body: SingleChildScrollView( child: Column(children: [HtmlWidget(stringHtml)]), ), floatingActionButton: Row( mainAxisAlignment: MainAxisAlignment.end, children: [ FloatingActionButton( onPressed: _exportHtmlToPdf, tooltip: '导出PDF', child: const Icon(Icons.picture_as_pdf), ), const SizedBox(width: 10), FloatingActionButton( onPressed: _openHtmlInBrowser, tooltip: '在浏览器打开', child: const Icon(Icons.open_in_browser), ), ], ), ); }
注意事项
- 桌面平台开发时,最新版本的
path_provider和url_launcher默认支持桌面端,无需额外配置。 - 若HTML包含复杂CSS或图片,优先选择printing库,它对样式的兼容性更好。
- Android平台可能需要申请存储权限,桌面平台无此限制。
内容的提问来源于stack exchange,提问作者Caio Abreu
相关产品推荐
相关产品推荐

