Updated on Feb 12th, 2021:
After more rounds of googling and digging into documentation, I have got it to work. Here are the main points:
1- There is no need to insert any javascript code into <app_directory>/web/index.html
file as I had pointed before. Sorry! I am learning flutter/dart...
2- I had to create a Future<html.Blob>
method (please have a look at myGetBlobPdfContent() async {...}
) to deal with html/pdf content, to save (await pdf.save()
) and to return a Blob
value. I'm not the right person to say it was related with a "non complete future" was throwing an null point on pdf stuff...
3- Also, Those RaisedButton's onPressed
methods were changed to async, to allow to get the pdf content as a Blob value (createObjectUrlFromBlob( await myGetBlobPdfContent());
).
4- Finally, I was having warning messages: Helvetica has no Unicode support see https://github.com/DavBfr/dart_pdf/wiki/Fonts-Management
, so that I have installed custom font like this cookbook instructions, in this example I have set up Arial ttf (data = await rootBundle.load("fonts/arial.ttf");
) and those warning messages went away.
5- Here is my pubspec.yaml
's snippet:
...
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- And an minimal working example (full main.dart
file):
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- At the end, the PDF generation (and download) is working as expected:
Hope this helps.
Initial post (Only to keep the information log)
@Spatz's answer might solve any pdf issue for web platform. I don't know why it is not working as expected, at least for my setup (see below).
I mean the webpage tries to open the pdf and throws an error: Failed to load PDF document.
Also, the example downloads a pdf file (some_name.pdf
) successfully, but it fails when I try to open the pdf file (error: file corrupted
).
I have seen that this post talks about insert javascript code into <app_directory>/web/index.html file. I have insert those lines and no success as well.
The source code I am using is a one main.dart
file:
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,
),
),
);
}
}
My setup is:
- Flutter (Channel beta, 1.26.0-17.3.pre, on Microsoft Windows [Version
10.0.19042.746],
locale en-150)
- Android tool chain develop for Android devices (Android SDK version
30.0.3)
- Chrome - develop for the web
- Android Studio (version 4.1.0)
Thank you :)