dart_pdf
dart_pdf copied to clipboard
Is there a way to make pdf.save non blocking on web?
I'm currently building a large pdf with this library but when saving and downloading, it blocks the main thread.
On mobile I can use Isolates but this will not work on web. Any suggestions here or someone that solved this already?
here is some example code:
import 'package:pdf/pdf.dart';
import 'package:printing/printing.dart';
import 'pdfdata.dart';
...
Future<void> generatePDF(
BuildContext context, List<PDFData> dataList) async {
final pw.Document pdf = pw.Document();
try {
for (final PDFData data in dataList) {
await generatePDFPages(context, data, pdf);
}
await Printing.sharePdf(bytes: await pdf.save(), filename: 'qr-code.pdf');
} catch (e) {
throw Exception('pdf generation error');
}
}
Future<void> generatedPDFPages(BuildContext context, PDFData data) async {
pdf.addPage(....)
}
@DavBfr any ideas?
There is no isolates on web, so I have no solution. This code is 100% Dart so it runs on the main thread.
yeah there is a still open issue for this. If i find some time I will try to use web workers + dart2js to simulate isolation on web.
maybe WASM support could also work (at least for newer browsers)
Or maybe https://pub.dev/packages/isolated_worker
The main issue here is not the isolation itself since web worker can do this. The critical part is the pdf library is written in dart but web worker needs js/wasm code to run so we need to do either dart2js so web worker can use the pdf library or dart2wasm to run wasm code in web worker instead. Will check once I find some time for this issue.
Is it possible to create a stream to which to subscribe that returns the pdf data the moment you manipulate the pdf (add page, text images, etc...) ?
I can't recommend Squadron highly enough, and it should be ~perfect for this --
only issue you can run into is if you import Flutter UI code, and thus can't dart2js it, but as we see above on Nov 20th, code is 100% Dart.
(I'm actually here because syncfusion_pdf touches Flutter UI code so I can't dart2js it, and I'm trolling through the repo to triple check if there's PDF -> text parsing code. Don't use the attached examples directly because they use SyncFusion, but it's enough for you to see what I've arrived at for best practice.)
Squadron: https://pub.dev/packages/squadron generate_js_script.txt pdf_parser_service.dart.txt
How about add pagePostProcessDoneCallback option to document.save()? ('package:pdf/widgets.dart')
It still block main thread, but has chance to make UI feedback (e.g. page processed progress)
I have extended Document class, and it seems below.
@override
Future<Uint8List> save({Function? pagePostProcessDoneCallback}) async {
if (!_paint) {
for (final page in _pages) {
page.postProcess(this);
if (pagePostProcessDoneCallback != null) {
await Future.delayed(const Duration(milliseconds: 5));
pagePostProcessDoneCallback.call();
}
}
_paint = true;
}
return await document.save();
}