我正在构建网站,在其中的一个部分中,我可以从动态值生成 pdf,然后将其下载到设备。可以生成并下载 pdf,但不能在浏览器中查看,它会返回空屏幕。我正在使用 pdf:^3.10.8(用于生成 pdf) syncfusion_flutter_pdfviewer:^20.4.54(用于在网络中查看 pdf)包。最重要的是控制台中没有错误需要解决。任何帮助将不胜感激。
我附上屏幕截图以便更好地理解
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:pdf/widgets.dart' as pw;
import 'package:syncfusion_flutter_pdfviewer/pdfviewer.dart';
class InvoicePreviewScreen extends StatefulWidget {
const InvoicePreviewScreen({super.key});
@override
State createState() => _InvoicePreviewScreenState();
}
class _InvoicePreviewScreenState extends State<InvoicePreviewScreen> {
Uint8List? invoiceBytes;
@override
void initState() {
super.initState();
generateInvoice().then((value) {
setState(() {
invoiceBytes = value;
});
});
}
Future<pw.Font> loadCustomFont() async {
final fontData = await rootBundle.load("assets/open-sans.ttf");
return pw.Font.ttf(fontData.buffer.asByteData());
}
Future<Uint8List> generateInvoice() async {
final cusFont = await loadCustomFont();
final pdf = pw.Document();
pdf.addPage(
pw.Page(
build: (pw.Context context) {
return pw.Center(
child: pw.Text("Invoice",
style: pw.TextStyle(fontSize: 40, font: cusFont)),
);
},
),
);
return pdf.save();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Invoice Preview'),
),
body: Center(
child: invoiceBytes != null
? SfPdfViewer.memory(
invoiceBytes!,
)
: const CircularProgressIndicator(),
),
);
}
}
这是我可以下载 pdf 但无法查看它的另一种方式
import 'dart:developer';
import 'dart:html' as html;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:pdf/widgets.dart' as pw;
import 'package:syncfusion_flutter_pdfviewer/pdfviewer.dart';
class PDFSave extends StatefulWidget {
const PDFSave({super.key});
@override
State createState() => _PDFSaveState();
}
class _PDFSaveState extends State<PDFSave> {
final pdf = pw.Document();
var anchor;
String? data;
Uint8List? pdfInBytes;
savePDF() async {
pdfInBytes = await pdf.save();
log("Save PDF: ${pdfInBytes.toString()}");
final blob = html.Blob([pdfInBytes], 'application/pdf');
final url = html.Url.createObjectUrlFromBlob(blob);
anchor = html.document.createElement('a') as html.AnchorElement
..href = url
..style.display = 'none'
..download = 'pdf.pdf';
html.document.body?.children.add(anchor);
}
createPDF() async {
final font = await rootBundle.load("assets/open-sans.ttf");
final ttf = pw.Font.ttf(font);
pdf.addPage(
pw.Page(
build: (pw.Context context) => pw.Column(
children: [
pw.Text('Hello World',
style: pw.TextStyle(fontSize: 40, font: ttf)),
],
),
),
);
await savePDF();
displayPDF();
}
displayPDF() {
log("Display PDF: ${pdfInBytes.toString()}");
data = Uri.dataFromBytes(
pdfInBytes!,
mimeType: 'application/pdf',
).toString();
log("Data Value: ${data.toString()}");
setState(() {});
}
@override
void initState() {
super.initState();
createPDF();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.transparent,
appBar: AppBar(
title: const Text('PDF Creator'),
),
body: Column(
children: [
data != null
? SizedBox(
height: 400,
width: 300,
child: SfPdfViewer.network(
data!,
),
)
: const CircularProgressIndicator(),
ElevatedButton(
child: const Text('Press'),
onPressed: () {
anchor.click();
Navigator.pop(context);
},
),
],
),
);
}
}
根据 syncfusion_flutter_pdfviewer
的文档在您的 web/index.html 文件中,在文档正文的某处添加以下脚本标签:
<script src="//cdnjs.cloudflare.com/ajax/libs/pdf.js/2.11.338/pdf.min.js"></script>
<script type="text/javascript">
pdfjsLib.GlobalWorkerOptions.workerSrc = "//cdnjs.cloudflare.com/ajax/libs/pdf.js/2.11.338/pdf.worker.min.js";
</script>