I am building the website where In a section I can generate a pdf from the dynamic values and then to download it to the device.The pdf can be generated and downloaded but not viewed in the browser it returns empty screen. I am using pdf: ^3.10.8(for pdf generating) syncfusion_flutter_pdfviewer: ^20.4.54 (for pdf viewing in web) packages. Most importantly there is no error in the console to resolve. Any help will be appreciated.
I am attaching my screen shots for better understanding
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(),
),
);
}
}
This is another way where i can download the pdf but cannot view it
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);
},
),
],
),
);
}
}
PDFSave screen: this is the ui I am getting where the button is working but the view is not this screenshot is associated with the second code format for the PDFSave screen(in the console there is no error)
As per the documentation of syncfusion_flutter_pdfviewer
On your web/index.html file, add the following script tags, somewhere in the body of the document: