pdfme_flutter 0.1.2
pdfme_flutter: ^0.1.2 copied to clipboard
Generate PDFs on-device from pdfme Designer templates. Pass template JSON and inputs, get PDF bytes — no server required.
pdfme_flutter #
Generate PDFs on the device from pdfme Designer templates.
Design the layout once in the pdfme Designer, then fill it with data in Flutter — no PDF server, no Designer UI in your app, no internet required after install.
final pdfBytes = await PdfmeGenerator.generate(
template: templateFromDesigner, // Map from Designer JSON
inputs: [
{
'billedToInput': 'Ada Lovelace',
'info': '{"InvoiceNo":"INV-001","Date":"4 Sep 2026"}',
},
],
);
pdfBytes is a Uint8List you can save, share, or preview.
| Platform | Supported |
|---|---|
| Android | Yes |
| iOS | Yes |
| Web / Desktop | Not yet |
How it works #
pdfme’s generator (@pdfme/generator) is a JavaScript library. Flutter cannot run it as Dart, so this plugin embeds a small offline JS runtime:
Your Flutter app
│ PdfmeGenerator.generate(template, inputs, options?)
▼
MethodChannel
▼
Android / iOS (offscreen WebView — never shown to the user)
▼
Bundled pdfme engine (engine.js)
▼
PDF bytes → back to Dart
- You export a template from the pdfme Designer (JSON with
basePdf+schemas). - Your app passes that template plus inputs (field values).
- The plugin loads a bundled copy of pdfme inside a hidden WebView.
- pdfme renders the PDF locally and returns the bytes.
You do not rewrite pdfme in Dart. You do not open a browser for the user. Generation stays on-device.
Install #
dependencies:
pdfme_flutter: ^0.1.2
flutter pub get
Usage #
1. Design a template #
Use the pdfme Designer (web) to lay out text, tables, images, QR codes, etc., then export / copy the template JSON.
2. Load it in Flutter #
import 'dart:convert';
import 'package:flutter/services.dart';
import 'package:pdfme_flutter/pdfme_flutter.dart';
final template = jsonDecode(
await rootBundle.loadString('assets/templates/invoice.json'),
) as Map<String, dynamic>;
3. Generate #
final inputs = [
{
// Keys must match schema `name` values from the Designer.
'billedToInput': 'Ada Lovelace\nLondon, UK',
'info': jsonEncode({
'InvoiceNo': 'INV-1001',
'Date': '4 September 2026',
}),
'orders': jsonEncode([
['Widget', '2', '10', '20'],
['Gadget', '1', '15', '15'],
]),
'taxInput': jsonEncode({'rate': '18'}),
'paymentInfoInput': 'Bank transfer due in 14 days',
},
];
final pdf = await PdfmeGenerator.generate(
template: template,
inputs: inputs,
);
// Save or share:
await File('invoice.pdf').writeAsBytes(pdf);
Only editable fields need values in inputs. Read-only labels from the Designer stay in the template.
Custom fonts #
Pass pdfme options.font through generate. Embed font bytes as data: URIs — the engine cannot download remote font files.
import 'dart:convert';
import 'package:flutter/services.dart';
final font = await rootBundle.load('assets/fonts/NotoSans-Regular.ttf');
final fontUri =
'data:font/ttf;base64,${base64Encode(font.buffer.asUint8List())}';
final pdf = await PdfmeGenerator.generate(
template: template,
inputs: inputs,
options: {
'font': {
'NotoSans': {
'data': fontUri,
'fallback': true,
},
},
},
);
Use the same font family names in the Designer template (fontName) as keys in options.font.
Errors #
Failures throw PdfmeException with a message and optional code (for example INVALID_INPUT, GENERATION_ERROR).
Images, fonts, and offline data #
- Prefer
data:URIs for images/signatures (nothttps://URLs). Remote URLs are rejected so generation stays offline. basePdfshould be a blank-pdf object or embeddeddata:application/pdf;base64,..., not a remote URL.- Custom fonts go in
options.fontasdata:font/ttf;base64,...(or otf/woff) values. The engine decodes those URIs to bytes becausefetchis disabled. Withoutoptions.font, pdfme’s bundled default font is used.
Example app #
cd example
flutter pub get
flutter run
The example loads a Designer invoice template and generates a PDF on a simulator/device.
Security notes #
- The WebView is offscreen and not a user-facing browser.
- Android blocks WebView network loads; iOS blocks
http(s)navigations/resources. - The JS layer stubs
fetch/XHRand rejects remotebasePdf/ barehttp(s)input values. - Treat templates and inputs as trusted app data (same as shipping any JS bundle in your app).
Rebuild the JS engine (maintainers) #
cd js
npm install
npm run build
That refreshes assets/pdfme/, Android assets, and iOS resources. Keep js/package-lock.json committed.
License #
MIT. This package bundles pdfme (@pdfme/generator and related packages), also MIT.
Not an official pdfme product — a community Flutter bridge so mobile apps can use Designer templates locally.