Add New Page in MultiPage Pdf Flutter - flutter

I use the pdf library and MultiPage, and I want to repeat the specific widget so that each widget is on a separate page. How do I do that?
I don't want to use addPage because I have a header, footer and some formats don't want to repeat it in every add page.
How can I add a new page to a MultiPage that already has the same formats?

// Create a PDF document.
final doc = pw.Document();
_logo = await rootBundle.loadString('assets/logo.svg');
_bgShape = await rootBundle.loadString('assets/invoice.svg');
=====> first_ Add page to the PDF <=======
doc.addPage(
pw.MultiPage(
pageTheme: _buildTheme(
pageFormat,
await PdfGoogleFonts.robotoRegular(),
await PdfGoogleFonts.robotoBold(),
await PdfGoogleFonts.robotoItalic(),
),
header: _buildHeader,
footer: _buildFooter,
build: (context) => [
//Insert to widget
],
),
);
======> second_ Add page to the PDF <========
doc.addPage(
pw.MultiPage(
pageTheme: _buildTheme(
pageFormat,
await PdfGoogleFonts.robotoRegular(),
await PdfGoogleFonts.robotoBold(),
await PdfGoogleFonts.robotoItalic(),
),
header: _buildHeader,
footer: _buildFooter,
build: (context) => [
//Insert to widget
],
),
);
// Return the PDF file content
return doc.save();

Related

how to solve pdf error inside flutter web html

hi I need to make my widgets as a pdf file but I have a problems with it
when i try to convert it to the pdf file it doesn't works and show this error message
Error: Assertion failed: org-dartlang-sdk:///flutter_web_sdk/lib/_engine/engine/html/scene_builder.dart:94:16
matrix4[0] == window.devicePixelRatio &&
matrix4[5] == window.devicePixelRatio
is not true
error doesn't appear when i render with an canvaskit but if i render with canvasKit images our making problem...
does any one knows how to solve this problem??
here is the code
void printScreen() {
Printing.layoutPdf(
onLayout: (PdfPageFormat format) async {
final doc = pw.Document();
final image = await WidgetWraper.fromKey(
key: reportsKey,
pixelRatio: 3.0,
);
doc.addPage(
pw.Page(
pageFormat: format,
build: (pw.Context context) {
return pw.Center(
child: pw.Expanded(
child: pw.Image(image),
),
);
},
),
);
return doc.save();
},
);
}

How to load image from assets folder inside a pdf in Flutter web?

We want to show image on a pdf from assets folder in Flutter web application:
import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart' as pw;
import 'package:flutter/material.dart';
.............
#override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Expanded(
child: Container(
height: 400,
width: 900,
child: PdfPreview(
build: (format) => _generatePdf(format, "SOME TITLE"),
)),
),
]));
}
Future<Uint8List> _generatePdf(PdfPageFormat format) async {
final pdf = pw.Document();
pdf.addPage(
pw.Page(
pageFormat: format,
build: (context) {
return pw.Image(AssetImage('assets/imglogo.png')); //This line gives the error
}));
return pdf.save();
}
This code gives error:
The argument type 'AssetImage' can't be assigned to the parameter type 'ImageProvider'
The documentation addresses only two cases To load an image from a file:(dart.io is not supported on the web), and To load an image from the network using the printing package:, which is not the case, so we tried the solutions provided here: 1,2, but each one gives a different exception.
Is there another approach to achieve this?
You can convert your ByteData directly to Uint8List as shown in the example code below. This can then be passed to the MemoryImage constructor:
Future<void> addPage(pw.Document pdf, String filename) async {
final imageByteData = await rootBundle.load('assets/$filename');
// Convert ByteData to Uint8List
final imageUint8List = imageByteData.buffer
.asUint8List(imageByteData.offsetInBytes, imageByteData.lengthInBytes);
final image = pw.MemoryImage(imageUint8List);
pdf.addPage(
pw.Page(
build: (pw.Context context) {
return pw.Center(
child: pw.Image(image),
); // Center
},
),
);
}
To achieve this you can get the asset image as a file, and then use this file in the PDF. If I take your code, we can add a function to get a File representation of your asset image :
Future<File> getImageFileFromAssets(String path) async {
final byteData = await rootBundle.load('assets/$path');
final file = File('${(await getTemporaryDirectory()).path}/$path');
await file.writeAsBytes(byteData.buffer
.asUint8List(byteData.offsetInBytes, byteData.lengthInBytes));
return file;
}
To make it works, you need to add path_provider to your dependencies.
Then you can use this function in your pdf generation function :
final pdf = pw.Document();
final file = await getImageFileFromAssets(yourpath);
final image = pw.MemoryImage(
file.readAsBytesSync(),
);
pdf.addPage(pw.Page(
pageFormat: format,
build: (context) {
return pw.Image(image);
}));
return pdf.save();

How to create multi pages pdf in flutter with images?

I have a list of file image paths. I need to create pdf from these images. How can I do it? I already know how to create pdf from a single image using pdf package.
Replace Page widget with MultiPage widget, default max pages is 20.
import 'package:pdf/pdf.dart';
import 'package:pdf/widgets.dart';
final pdf = Document();
pdf.addPage(
MultiPage(
pageFormat: PdfPageFormat.a4,
build: (Context context) => <Widget>[*/your widgets here*/],
)
)
Check out pdf library. The documentation contains example codes which will let you create a pdf file with multiple pages with images inside.
final image = PdfImage.file(
pdf.document,
bytes: File('test.webp').readAsBytesSync(),
);
final pdf = pw.Document();
final image = PdfImage.file(
pdf.document,
bytes: File('test.webp').readAsBytesSync(),
);
pdf.addPage(pw.Page(
build: (pw.Context context) {
return pw.Center(
child: pw.Image(image),
); // Center
})); // Page
final file = File("example.pdf");
await file.writeAsBytes(pdf.save());

PDF File generation with Flutter web

I'm in the process of Web'ifing a Flutter mobile application and attempting to get around the lack for support for Path Provider in Web.
I'm using the PDF (pdf: ^1.9.0) package to generate a PDF document and upload it to Google Drive and I'm trying to find out if I can generate and store the PDF In memory to make it web compatible.
Example current code using Path Provider.
createFile() async {
final downloads = await getApplicationSupportDirectory();
final file = File("${downloads.path}/$filename.pdf");
await file.writeAsBytes(pdf.save());
await GoogleDriveController.uploadFileToGoogleDrive(file.path);
}
Question: Is there a way to generate and store Fies in memory for web using Flutter web?
I managed to find a work around to generate the PDF and trigger a download via the browser instead and thought I should post incase anyone stumbles across this.
//Create PDF in Bytes
Uint8List pdfInBytes = pdf.save();
//Create blob and link from bytes
final blob = html.Blob([pdfInBytes], 'application/pdf');
final url = html.Url.createObjectUrlFromBlob(blob);
final anchor = html.document.createElement('a') as html.AnchorElement
..href = url
..style.display = 'none'
..download = 'pdf.pdf';
html.document.body.children.add(anchor);
//Trigger the download of this PDF in the browser.
RaisedButton(
child: Text('Press'),
onPressed: () {
anchor.click();
Navigator.pop(context);
},
)
My answer is a variant on Yonkee above specifically for flutter web. In this answer, I have added the imports required (dart:html and dart:typed_data) and added formatting of text as I needed that feature.
import 'package:flutter/material.dart';
import 'package:pdf/widgets.dart' as pw;
import 'dart:typed_data';
import 'dart:html' as html;
class PDFSave extends StatefulWidget {
#override
_PDFSaveState createState() => _PDFSaveState();
}
class _PDFSaveState extends State<PDFSave> {
final pdf = pw.Document();
var anchor;
savePDF() async {
Uint8List pdfInBytes = await pdf.save();
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 {
pdf.addPage(
pw.Page(
build: (pw.Context context) => pw.Column(
children: [
pw.Text('Hello World', style: pw.TextStyle(fontSize: 40)),
],
),
),
);
savePDF();
}
#override
void initState() {
super.initState();
createPDF();
}
#override
Widget build(BuildContext context) {
return Scaffold(backgroundColor: Colors.transparent,
appBar: AppBar(
title: Text('PDF Creator'),
),
body: Center(
child:RaisedButton(
child: Text('Press'),
onPressed: () {
anchor.click();
Navigator.pop(context);
},
)
));
}
}

Load pdf file from url

I have this url from server
https://xxxx.pdf20200529". How can I load it as pdf in my flutter app?
I use this plugin, but nothing happened.
Code
OpenFile.open(value); // value is https://xxxx.pdf20200529
Edit
generatePDF(dynamic value) async {
final filename = value.substring(value.lastIndexOf("/") + 1);
var request = await HttpClient().getUrl(Uri.parse(value));
var response = await request.close();
var bytes = await consolidateHttpClientResponseBytes(response);
String dir = (await getApplicationDocumentsDirectory()).path;
File file = new File('$dir/$filename');
await file.writeAsBytes(bytes);
OpenFile.open(file.path);
}
Opening PDF's in Flutter is pretty fiddly. So I suggest you use a package. flutter_full_pdf_viewer works pretty well and is easy to use, but there are others out there.
https://pub.dev/packages/flutter_full_pdf_viewer
This will be your PDF Screen:
class PDFScreen extends StatelessWidget {
String pathPDF = "";
PDFScreen(this.pathPDF);
#override
Widget build(BuildContext context) {
return PDFViewerScaffold(
appBar: AppBar(
title: Text("Document"),
actions: <Widget>[
IconButton(
icon: Icon(Icons.share),
onPressed: () {},
),
],
),
path: pathPDF);
}
}
Navigate to it like this. Make sure to pass the local path to the screen.:
Navigator.push(context, MaterialPageRoute(builder: (context) => PDFScreen(pathPDF)),
Have you tried url_launcher 5.4.10
As far as I know it opens pdfs as well.
I miss .pdf in this line
File file = new File('$dir/$filename.pdf');
After add .pdf, all PDF viewer able to open.