pdfme
Make PDF files from pdfme templates in Dart with dox_pdf_me, and send them from a Dox controller.
You design the template in the pdfme designer, then fill it with data on the server. dox_pdf_me reads the same template JSON as pdfme, and the PDF looks the same.
The package is standalone. It does not need Dox, and Dox does not need it. It is built on PDF Library.
Install
Fill a template in a controller
Design the template in the pdfme designer and save its JSON. Read it with Template.fromJson. The inputs are one map of strings for each copy of the template.
A controller can return a DownloadableFile. Dox streams the bytes and sets Content-Type and Content-Disposition. The browser saves the file. See Response.
Use StreamFile instead to show the PDF in the browser tab.
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'package:dox_core/dox_core.dart';
import 'package:dox_pdf_me/dox_pdf_me.dart';
@Inject()
class InvoiceController {
Future<DownloadableFile> show(DoxRequest req) async {
Map<String, Object?> json =
jsonDecode(File('storage/invoice.template.json').readAsStringSync())
as Map<String, Object?>;
Uint8List bytes = await generate(
template: Template.fromJson(json),
inputs: <Map<String, String>>[
<String, String>{'customer': 'Jane Doe', 'total': '120.00'},
],
plugins: builtInPlugins,
);
return DownloadableFile(
ContentType('application', 'pdf'),
Stream<List<int>>.value(bytes),
'invoice.pdf',
length: bytes.length,
);
}
}
dox_pdf_me supports text, image, svg, shapes, barcodes and QR codes, date and time, checkbox, radio group, select, table, multi variable text, signature and circle mark. Pass builtInPlugins to use all of them.
Fonts
Text uses Roboto by default. For other languages, pass your fonts in GenerateOptions:
Uint8List noto = File('NotoSansJP-Regular.otf').readAsBytesSync();
Uint8List pdf = await generate(
template: template,
inputs: inputs,
plugins: builtInPlugins,
options: GenerateOptions(
font: <String, FontSource>{
'Roboto': FontStore.defaultFont,
'NotoSansJP': FontSource(noto),
},
),
);
Thai, Myanmar, Khmer, Lao, Arabic, Hebrew and Hindi text is laid out correctly. Line breaks in Myanmar, Thai, Khmer and Lao go between words.
Platforms
dox_pdf_me uses dox_pdf_lib, which has a small native library. It runs in Dart programs on macOS, Linux and Windows.
They do not run on the web, iOS or Android.
A ready-built native library is downloaded for you, so you do not need Rust.
On Linux, the ready-built library needs glibc 2.35 or newer, for example Ubuntu 22.04 or Debian 12. On older Linux, or on Alpine, build the library yourself. The dox_pdf_lib README shows how.
Without Dox
The same code works in any Dart program. Call generate(...), then write the bytes to a file:
import 'dart:io';
import 'dart:typed_data';
import 'package:dox_pdf_me/dox_pdf_me.dart';
Future<void> main() async {
Uint8List pdf = await generate(
template: Template(
basePdf: const BlankPdf(),
schemas: <List<Schema>>[
<Schema>[
const TextSchema(name: 'title', position: Position(20, 20), width: 170, height: 15),
BarcodeSchema(name: 'link', barcodeType: BarcodeType.qrcode, position: const Position(20, 40)),
],
],
),
inputs: <Map<String, String>>[
<String, String>{'title': 'Hello, PDF!', 'link': 'https://dartondox.dev'},
],
plugins: builtInPlugins,
);
File('hello.pdf').writeAsBytesSync(pdf);
}
Learn more
dox_pdf_meon pub.dev: schema types, tables, plugins, fonts and options, and how to build a template in Dart.- Source on GitHub