2021 年 2 月 12 日更新:
经过多轮谷歌搜索和深入研究文档,我已经开始工作了。以下是要点:
1- 无需像我之前指出的那样将任何 javascript 代码插入到 <app_directory>/web/index.html 文件中。对不起!我正在学习颤振/飞镖...
2- 我必须创建一个 Future<html.Blob> 方法(请查看 myGetBlobPdfContent() async {...} )来处理 html/pdf 内容、保存 (await pdf.save()) 并返回 Blob 值。我不适合说它与“不完整的未来”有关,在 pdf 的东西上扔了一个空点......
3- 此外,那些 RaisedButton 的 onPressed 方法已更改为异步,以允许将 pdf 内容作为 Blob 值 (createObjectUrlFromBlob( await myGetBlobPdfContent());)。
4- 最后,我收到了警告消息:Helvetica has no Unicode support see https://github.com/DavBfr/dart_pdf/wiki/Fonts-Management,因此我安装了自定义字体,如 this cookbook instructions,在此示例中,我设置了 Arial ttf (data = await rootBundle.load("fonts/arial.ttf");),这些警告消息消失了。
5- 这是我的pubspec.yaml 的sn-p:
...
dependencies:
flutter:
sdk: flutter
pdf: ^2.1.0
universal_html: ^1.2.4
...
fonts:
- family: Arial
fonts:
- asset: fonts/arial.ttf
- asset: fonts/arialbd.ttf
weight: 700
- asset: fonts/ariali.ttf
style: italic
...
6- 还有一个最小的工作示例(完整的main.dart 文件):
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart' as pw;
import 'package:universal_html/html.dart' as html;
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: PdfDemo(),
);
}
}
class PdfDemo extends StatelessWidget {
Future<html.Blob> myGetBlobPdfContent() async {
var data = await rootBundle.load("fonts/arial.ttf");
var myFont = pw.Font.ttf(data);
var myStyle = pw.TextStyle(font: myFont, fontSize: 36.0);
final pdf = pw.Document();
pdf.addPage(pw.Page(
pageFormat: PdfPageFormat.a4,
build: (pw.Context context) {
return pw.Center(
child: pw.Text(
"Hello World",
style: myStyle,
),
// child: pw.Text("Hello World", style: myStyle),
);
}));
final bytes = await pdf.save();
html.Blob blob = html.Blob([bytes], 'application/pdf');
return blob;
}
@override
Widget build(BuildContext context) {
myGetBlobPdfContent();
return Scaffold(
appBar: AppBar(),
body: Center(
child: Column(
children: <Widget>[
RaisedButton(
child: Text("Open"),
onPressed: () async {
final url = html.Url.createObjectUrlFromBlob(
await myGetBlobPdfContent());
html.window.open(url, "_blank");
html.Url.revokeObjectUrl(url);
},
),
RaisedButton(
child: Text("Download"),
onPressed: () async {
final url = html.Url.createObjectUrlFromBlob(
await myGetBlobPdfContent());
final anchor =
html.document.createElement('a') as html.AnchorElement
..href = url
..style.display = 'none'
..download = 'some_name.pdf';
html.document.body.children.add(anchor);
anchor.click();
html.document.body.children.remove(anchor);
html.Url.revokeObjectUrl(url);
},
),
],
mainAxisAlignment: MainAxisAlignment.center,
),
),
);
}
}
7- 最后,PDF 生成(和下载)按预期工作:
希望这会有所帮助。
初次发帖(仅保留信息日志)
@Spatz 的回答可能会解决网络平台的任何 pdf 问题。我不知道为什么它没有按预期工作,至少对于我的设置(见下文)。
我的意思是网页尝试打开pdf并抛出错误:Failed to load PDF document.
此外,该示例成功下载了一个 pdf 文件 (some_name.pdf),但是当我尝试打开该 pdf 文件 (error: file corrupted) 时它失败了。
我看到this post 谈到将javascript 代码插入/web/index.html 文件。我已经插入了这些行,也没有成功。
我使用的源代码是一个main.dart文件:
import 'package:flutter/material.dart';
import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart' as pw;
import 'package:universal_html/html.dart' as html;
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: PdfDemo(),
);
}
}
class PdfDemo extends StatelessWidget {
@override
Widget build(BuildContext context) {
final pdf = pw.Document();
pdf.addPage(pw.Page(
pageFormat: PdfPageFormat.a4,
build: (pw.Context context) {
return pw.Center(
child: pw.Text("Hello World"),
);
}));
final bytes = pdf.save();
final blob = html.Blob([bytes], 'application/pdf');
return Scaffold(
appBar: AppBar(),
body: Center(
child: Column(
children: <Widget>[
RaisedButton(
child: Text("Open"),
onPressed: () {
final url = html.Url.createObjectUrlFromBlob(blob);
html.window.open(url, "_blank");
html.Url.revokeObjectUrl(url);
},
),
RaisedButton(
child: Text("Download"),
onPressed: () {
final url = html.Url.createObjectUrlFromBlob(blob);
final anchor =
html.document.createElement('a') as html.AnchorElement
..href = url
..style.display = 'none'
..download = 'some_name.pdf';
html.document.body.children.add(anchor);
anchor.click();
html.document.body.children.remove(anchor);
html.Url.revokeObjectUrl(url);
},
),
],
mainAxisAlignment: MainAxisAlignment.center,
),
),
);
}
}
我的设置是:
- Flutter(频道测试版,1.26.0-17.3.pre,在 Microsoft Windows [版本
10.0.19042.746],
语言环境 en-150)
- Android工具链为Android设备开发(Android SDK版本
30.0.3)
- Chrome - 为网络开发
- Android Studio(4.1.0 版)
谢谢你:)