Сохранение pdf файла во Flutter web

Егор Долгов · 31.10.2019
Archive material: it describes Flutter as of publication and is not updated.

Если кто-то столкнулся с проблемой сохранения бинарных файлов во Flutter web, в том числе PDF файлов, предлагаем наше решение.

Для вывода бинарного файла в браузере воспользуемся функцией JavaScript, ее нужно подключить в index.html:

function ToFile(arg) {
    let blob = new Blob([arg], {type: "application/pdf"});
    let objectUrl = URL.createObjectURL(blob);
    window.open(objectUrl)
  }

Пакет pdf https://pub.dev/packages/pdf позволяет создавать PDF документы на основе виджетов аналогичных Flutter виджетам. Но при использовании во Flutter, чтобы избежать конфликтов с одинаковыми названиями классов, используем import ' ' as PDF. Пакет file https://pub.dev/packages/file позволяет создать экземпляр класса File в памяти. И после вывести содержимое в нужном формате для передачи в JavaScript функцию ToFile.

Подключение зависимостей pdf и file

dependencies:
  pdf: 1.3.23
  file: 5.1.0

Использование пакетов

import 'dart:js' as JS;// Для вызова JavaScript функции ToFile();
import 'dart:io';// Используем класс File
import 'package:file/memory.dart';// Используем этот пакет для записи файла в память
import 'package:pdf/pdf.dart' as PDF;// PDF.PdfPageFormat и др.
import 'package:pdf/widgets.dart' as PDF;// PDF.Document, PDF.Page и др.

Код создания и сохранения PDF файла

final pdf = PDF.Document();
pdf.addPage(PDF.Page(
  pageFormat: PDF.PdfPageFormat.a5,
  build: (PDF.Context context) {
    return PDF.Center(child: PDF.Text("Hello World")); // Center
  })); // Page

File file = MemoryFileSystem().file('example.pdf')..writeAsBytesSync(pdf.save());
JS.context.callMethod('ToFile', [file.readAsBytesSync()]);

Открыть пример в отдельном окне: https://app4.flutter.su

<!-- video: https://app4.flutter.su -->