fdevs_web_processor
A Flutter plugin for rendering HTML to PDF on Android.
Features
- HTML to PDF — Convert any HTML string into a PDF document.
- Continuous mode — Generate single-page, dynamically-sized PDFs perfect for thermal receipts and long invoices.
- Paginated mode — Fixed page sizes ideal for A4 documents, letters, and reports.
- Built-in page sizes — Quick presets for
a4,a5,letter,legal,mm80, andmm58thermal rolls. - Configurable margins — Control margins in PDF points (1/72 inch).
- Asset loading — Automatically waits for images, stylesheets, and fonts with a configurable timeout.
- Post-load script — Inject custom JavaScript to modify the DOM before capture.
- Typed exceptions — Clear, actionable error messages for every failure mode.
Platform Support
| Android | iOS |
|---|---|
| ✅ | ⏳ |
- Android: API 19+ (fully implemented)
- iOS: Planned for a future release
Installation
flutter pub add fdevs_web_processor
Usage
Basic example — A4 invoice
import 'dart:io';
import 'dart:typed_data';
import 'package:fdevs_web_processor/fdevs_web_processor.dart';
Future<void> generateInvoice() async {
final html = '''
<html>
<body style="font-family: Arial; padding: 40px;">
<h1>Invoice #001</h1>
<p>Total: \$100.00</p>
</body>
</html>
''';
final Uint8List pdf = await FdevsWebProcessor.renderToPdf(
html: html,
config: const RenderConfig(
width: PageSize.a4.width,
height: PageSize.a4.height,
margins: RenderMargins.all(36), // 0.5 inch margins
),
);
await File('invoice.pdf').writeAsBytes(pdf);
}
Thermal receipt — 80mm continuous
Future<void> generateReceipt() async {
final html = '''
<html>
<body style="font-family: monospace; font-size: 12px;">
<h2>MY STORE</h2>
<p>Item 1 .............. \$10.00</p>
<p>Item 2 .............. \$15.50</p>
<hr/>
<p><strong>Total: \$25.50</strong></p>
<p>Thank you!</p>
</body>
</html>
''';
final Uint8List pdf = await FdevsWebProcessor.renderToPdf(
html: html,
config: const RenderConfig(
width: PageSize.mm80.width, // 80mm roll width
continuousMode: true, // Single continuous page
margins: RenderMargins.symmetric(horizontal: 5),
),
);
await File('receipt.pdf').writeAsBytes(pdf);
}
API Reference
FdevsWebProcessor.renderToPdf
static Future<Uint8List> renderToPdf({
required String html,
RenderConfig config = const RenderConfig(),
});
Renders the given html to a PDF document using the specified config.
Throws:
InvalidInputException— HTML is empty or config is invalid.WebViewException— WebView initialization or load failure.AssetTimeoutException— Assets failed to load in time.PdfExportException— PDF generation failed.ContentTooLargeException— Content exceeds the maximum renderable height.
RenderConfig
const RenderConfig({
double? width, // Output width in PDF points
double? height, // Output height in PDF points
RenderMargins margins, // Page margins
double devicePixelRatio, // Reserved for future use (default: 2.0)
int assetLoadTimeoutMs, // Max time to wait for assets (default: 10000)
bool continuousMode, // Single continuous page (default: false)
String? baseUrl, // Base URL for relative assets
String? postLoadScript, // JS to run before capture
});
PageSize presets
| Preset | Dimensions | Use case |
|---|---|---|
PageSize.a4 |
595 × 842 pt | Standard documents |
PageSize.a5 |
420 × 595 pt | Small documents |
PageSize.letter |
612 × 792 pt | US documents |
PageSize.legal |
612 × 1008 pt | Legal documents |
PageSize.mm80 |
226 pt width, auto height | 80mm thermal receipts |
PageSize.mm58 |
164 pt width, auto height | 58mm thermal receipts |
Error Handling
All errors are thrown as subclasses of RenderException:
try {
final pdf = await FdevsWebProcessor.renderToPdf(html: html);
} on ContentTooLargeException catch (e) {
// Content too tall — consider splitting into multiple documents
print('Content height: ${e.contentHeightPx}px (max: ${e.maxHeightPx}px)');
} on RenderException catch (e) {
// All other rendering errors
print('Error [${e.code}]: ${e.message}');
}
Android Permissions
The plugin requires the INTERNET permission to load external images, fonts, and stylesheets. This is already declared in the plugin's AndroidManifest.xml, so no additional setup is needed.
Testing
Unit tests
flutter test
Android integration tests
Integration tests run on a real device or emulator via the example app:
./tool/run_android_integration_test.sh
Or manually:
cd example
flutter test integration_test/plugin_integration_test.dart -d <device-id>
Additional information
For more help getting started with Flutter, view the online documentation, which offers tutorials, samples, guidance on mobile development, and a full API reference.