filepdfflutterflutter-webuint8list

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:

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.)


Solution

  • 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 'dart:html' as html;
    import 'package:flutter/material.dart';
    import 'package:pdf/pdf.dart';
    import 'package:pdf/widgets.dart' as pw;
    
    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,
            ),
          ),
        );
      }
    }