Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flutter web - display pdf file generated in application. (Uint8List format)

I am working on a iOS/Android/Web app where I am generating a PDF based on user input using the pdf plugin here: https://pub.dev/packages/pdf. On iOS and Android, I have access to the file system, so I am able to save the generated pdf first, and then open it with any pdf display plugin.

However, for Flutter web, as far as I know, there is no access to any type of file system. All the pdf render plugins that I've seen assume that the pdf file is either stored in a file, or on the web. I looked at:

  • flutter_full_pdf_viewer: ^1.0.6
  • flutter_pdf_viewer: ^0.6.1
  • pdf_render: ^0.57.2

How can I display this app-generated pdf on flutter web? Is there a way to spoof the Uint8List data as a file, or perhaps another way to approach this? (The only thing I can think of to solve this is by uploading the file to the web after generating it in order to display it, but it seems like overkill.)

like image 723
William Terrill Avatar asked Apr 22 '20 19:04

William Terrill


People also ask

How do I display a PDF from assets in flutter?

Step 1: Create a new directory in the root directory of the project and name it as "assets”. Added the PDF document inside the new directory as shown in the following image. Step 2: Add the PDF document in the assets section of pubspec. yaml file.


1 Answers

We can do it without additional plug-ins, because the web browser itself can display (or download) pdf document.

updated for pdf 2.0.0 and newer

Since method save now returns Future, button handlers become asynchronous (of course you can use FurureBuilder or something else).

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;

class PdfLabPage 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'),
          );
        }));

    return Scaffold(
      appBar: AppBar(),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
              onPressed: () async {
                final bytes = await pdf.save();
                final blob = html.Blob([bytes], 'application/pdf');
                final url = html.Url.createObjectUrlFromBlob(blob);
                html.window.open(url, '_blank');
                html.Url.revokeObjectUrl(url);
              },
              child: Text('Open'),
            ),
            ElevatedButton(
              onPressed: () async {
                final bytes = await pdf.save();
                final blob = html.Blob([bytes], 'application/pdf');
                final url = html.Url.createObjectUrlFromBlob(blob);
                final anchor = 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);
              },
              child: Text('Download'),
            ),
          ],
        ),
      ),
    );
  }
}

original answer

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;

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,
        ),
      ),
    );
  }
}
like image 129
Spatz Avatar answered Nov 09 '22 20:11

Spatz