flutter_receipt_printer 1.0.0
flutter_receipt_printer: ^1.0.0 copied to clipboard
A modern Bluetooth thermal printer plugin for Flutter. Supports ESC/POS receipts, TSC labels, QR codes, barcodes, and Unicode on Android, iOS, macOS, Windows & Linux.
flutter_receipt_printer #
A modern Bluetooth thermal printer plugin for Flutter with support for ESC/POS and TSC commands. Designed as an actively maintained alternative to the outdated bluetooth_print package.
Features #
- Device Discovery — Scan and discover nearby Bluetooth devices
- Connection Management — Connect/disconnect with stream-based status monitoring
- ESC/POS Support — Print receipts with text formatting, alignment, bold, underline, and font sizing
- TSC Label Support — Print labels with custom positioning and layout
- QR Codes & Barcodes — Generate and print QR codes and various barcode formats
- Image Printing — Print images on thermal printers
- Unicode Support — Full Unicode text including emojis, symbols, and multiple languages
- Indian Languages — Complete support for Hindi, Tamil, Bengali, Telugu, Marathi, Gujarati, Kannada, Malayalam, Punjabi, Odia
- Multiple Encodings — UTF-8, Latin-1, CP1252, CP850, CP437
- Cross Platform — Android (Classic BT), iOS, macOS, Windows, and Linux (BLE)
- Auto Reconnect — Remembers last connected printer via SharedPreferences
- Modern Architecture — Null-safe, singleton API, stream-based reactive updates
Platform Support #
| Platform | Transport | Supported |
|---|---|---|
| Android | Classic Bluetooth (RFCOMM/SPP) via flutter_bluetooth_serial |
✅ |
| iOS | BLE via flutter_blue_plus |
✅ |
| macOS | BLE via flutter_blue_plus |
✅ |
| Windows | BLE via flutter_blue_plus_winrt (auto-included) |
✅ |
| Linux | BLE via flutter_blue_plus |
✅ |
Note: Android uses Classic Bluetooth, which is how most cheap thermal printers connect. iOS, macOS, Windows, and Linux use BLE — your printer must advertise a BLE service (most modern 58 mm printers do).
Installation #
Add to your pubspec.yaml:
dependencies:
flutter_receipt_printer: ^1.0.0
Then run:
flutter pub get
Permissions #
Android #
Add to android/app/src/main/AndroidManifest.xml:
<!-- Legacy Bluetooth (Android ≤ 11) -->
<uses-permission android:name="android.permission.BLUETOOTH"
android:maxSdkVersion="30"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"
android:maxSdkVersion="30"/>
<!-- Bluetooth (Android 12+) -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"
android:usesPermissionFlags="neverForLocation"/>
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
iOS #
Add to ios/Runner/Info.plist:
<key>NSBluetoothAlwaysUsageDescription</key>
<string>This app needs Bluetooth to connect to your thermal receipt printer.</string>
<key>NSBluetoothPeripheralUsageDescription</key>
<string>This app needs Bluetooth to connect to your thermal receipt printer.</string>
macOS #
- Add to
macos/Runner/Info.plist:
<key>NSBluetoothAlwaysUsageDescription</key>
<string>This app needs Bluetooth to connect to your thermal receipt printer.</string>
- Add to both
macos/Runner/DebugProfile.entitlementsandmacos/Runner/Release.entitlements:
<key>com.apple.security.device.bluetooth</key>
<true/>
Without the entitlement the macOS sandbox silently blocks all BLE access, even if
Info.plisthas the usage description.
Windows #
No manifest changes required. The flutter_blue_plus_winrt package (automatically included as a federated plugin) handles Bluetooth access through the Windows Runtime APIs. The OS-level Bluetooth toggle must be enabled in Windows Settings.
Linux #
No manifest changes required. Ensure the bluetooth service is running:
sudo systemctl enable --now bluetooth
Quick Start #
import 'package:flutter_receipt_printer/flutter_receipt_printer.dart';
final printer = FlutterPrinter.instance;
// Listen to connection and scan updates
printer.connectionStream.listen((status) => print('Status: $status'));
printer.scanStream.listen((devices) => print('Found: ${devices.length}'));
// Scan and connect
await printer.startScan(timeout: const Duration(seconds: 10));
await printer.connect(discoveredDevices.first);
// Print
await printer.printText('Hello World!');
await printer.disconnect();
Usage #
Scanning for Devices #
// Start scanning
await printer.startScan(timeout: const Duration(seconds: 10));
// Stop scanning
await printer.stopScan();
Connecting to a Printer #
// Connect
await printer.connect(device);
// Check status
if (printer.connectionStatus == ConnectionStatus.connected) {
print('Connected to: ${printer.connectedDevice?.name}');
}
// Disconnect
await printer.disconnect();
Printing Text (ESC/POS) #
// Simple text
await printer.printText('Hello World!');
// Formatted text
await printer.printText(
'Receipt Header',
config: PrintConfig(
alignment: PrintAlignment.center,
bold: true,
fontSize: 1,
),
);
// Full receipt example
await printer.printText('My Store', config: PrintConfig(
alignment: PrintAlignment.center,
bold: true,
));
await printer.printText('Item 1: \$10.00');
await printer.printText('Item 2: \$15.00');
await printer.printText('-------------------');
await printer.printText('Total: \$25.00', config: PrintConfig(bold: true));
await printer.printEscPos(EscPosCommands.feedLines(3));
await printer.printEscPos(EscPosCommands.cutPaper());
Printing QR Codes and Barcodes #
// QR code
await printer.printQrCode('https://example.com', size: 6);
// Barcode
await printer.printBarcode('1234567890', height: 162, width: 2);
Label Printing (TSC) #
await printer.printLabel(
width: 50,
height: 30,
gap: 2,
commands: [
TscCommands.text(x: 10, y: 10, text: 'Product Name'),
TscCommands.qrCode(x: 10, y: 50, data: 'https://example.com'),
TscCommands.barcode(x: 200, y: 50, data: '1234567890'),
],
);
Unicode & Indian Languages #
// Chinese / multilingual
await printer.printText('Hello! 你好世界!', config: PrintConfig(
encoding: TextEncoding.utf8,
));
// Hindi (Devanagari)
await printer.printText('नमस्ते! आप कैसे हैं?', config: PrintConfig(
encoding: TextEncoding.utf8,
));
// Tamil
await printer.printText('வணக்கம்!', config: PrintConfig(
encoding: TextEncoding.utf8,
));
// Indian Rupee symbol
await printer.printText('Total: ₹1,500.00');
// Older printer fallback
await printer.printText('Café résumé', config: PrintConfig(
encoding: TextEncoding.latin1,
));
Indian Business Receipt Example #
await printer.printText('राज इलेक्ट्रॉनिक्स', config: PrintConfig(
alignment: PrintAlignment.center,
bold: true,
encoding: TextEncoding.utf8,
));
await printer.printText('रसीद संख्या / Receipt No: 001');
await printer.printText('कुल राशि / Total: ₹2,500.00');
await printer.printText('धन्यवाद! / Thank You!');
API Reference #
FlutterPrinter #
Singleton main class — use FlutterPrinter.instance.
| Member | Type | Description |
|---|---|---|
connectionStatus |
ConnectionStatus |
Current connection state |
connectedDevice |
BluetoothDeviceModel? |
Currently connected device |
connectionStream |
Stream<ConnectionStatus> |
Connection state stream |
scanStream |
Stream<List<BluetoothDeviceModel>> |
Device scan results stream |
startScan({Duration timeout}) |
Future<void> |
Start scanning for nearby devices |
stopScan() |
Future<void> |
Stop scanning |
connect(device) |
Future<void> |
Connect to a device |
disconnect() |
Future<void> |
Disconnect from current device |
printText(text, {config}) |
Future<void> |
Print formatted text (ESC/POS) |
printQrCode(data, {size}) |
Future<void> |
Print QR code |
printBarcode(data, {height, width}) |
Future<void> |
Print barcode |
printLabel({width, height, gap, commands}) |
Future<void> |
Print TSC label |
printEscPos(bytes) |
Future<void> |
Send raw ESC/POS bytes |
Models #
BluetoothDeviceModel
| Property | Type | Description |
|---|---|---|
name |
String |
Device name |
address |
String |
Bluetooth address |
isPaired |
bool |
Whether device is paired |
rssi |
int? |
Signal strength (if available) |
PrintConfig
| Property | Type | Description |
|---|---|---|
alignment |
PrintAlignment |
Text alignment |
bold |
bool |
Bold formatting |
underline |
bool |
Underline formatting |
fontSize |
int |
Font size (0–2) |
lineSpacing |
int |
Line spacing |
encoding |
TextEncoding |
Character encoding |
Enums #
ConnectionStatus: disconnected · connecting · connected · error
PrintAlignment: left · center · right
TextEncoding: utf8 · latin1 · cp1252 · cp850 · cp437
Indian Languages Support #
| Language | Script | Example |
|---|---|---|
| Hindi | Devanagari | नमस्ते! आप कैसे हैं? |
| Tamil | Tamil | வணக்கம்! நீங்கள் எப்படி இருக்கிறீர்கள்? |
| Bengali | Bengali | নমস্কার! আপনি কেমন আছেন? |
| Telugu | Telugu | నమస్కారం! మీరు ఎలా ఉన్నారు? |
| Marathi | Devanagari | नमस्कार! तुम्ही कसे आहात? |
| Gujarati | Gujarati | નમસ્તે! તમે કેમ છો? |
| Kannada | Kannada | ನಮಸ್ಕಾರ! ನೀವು ಹೇಗಿದ್ದೀರಿ? |
| Malayalam | Malayalam | നമസ്കാരം! നിങ്ങൾ എങ്ങനെയുണ്ട്? |
| Punjabi | Gurmukhi | ਸਤ ਸ੍ਰੀ ਅਕਾਲ! ਤੁਸੀਂ ਕਿਵੇਂ ਹੋ? |
| Odia | Odia | ନମସ୍କାର! ଆପଣ କେମିତି ଅଛନ୍ତି? |
Always use
TextEncoding.utf8for Indian scripts. Some hardware may show boxes if the printer firmware lacks Indic font support.
Comparison with bluetooth_print #
| Feature | flutter_receipt_printer | bluetooth_print |
|---|---|---|
| Last Updated | 2025 | 2022 |
| Null Safety | ✅ | ❌ |
| Android (Classic BT) | ✅ | ✅ |
| iOS (BLE) | ✅ | ✅ |
| macOS | ✅ | ❌ |
| Windows | ✅ | ❌ |
| Linux | ✅ | ❌ |
| Unicode | ✅ Full | ❌ Limited |
| Indian Languages | ✅ Complete | ❌ None |
| Multiple Encodings | ✅ | ❌ |
| Stream-based API | ✅ | ❌ |
| TSC Labels | ✅ | ✅ |
| ESC/POS | ✅ | ✅ |
| Auto Reconnect | ✅ | ❌ |
Example App #
Check the example/ directory for a complete demo. Run with:
cd example
flutter pub get
flutter run
The example app covers:
- Basic usage — scanning, connecting, simple printing
- Unicode examples — multilingual text and special characters
- Indian languages — Hindi, Tamil, Bengali, Telugu, and more
- Advanced examples — real-world receipts, invoices, and TSC labels
Troubleshooting #
- Permission denied — Ensure all required permissions and entitlements are added for the target platform (see Permissions).
- Connection failed — Check if the device is already connected to another app or another phone.
- Nothing prints — Verify the printer supports ESC/POS or TSC commands.
- Android 12+ — Location permission is required for Bluetooth scanning even if you don't use location.
- macOS — no scan results:
- Confirm
com.apple.security.device.bluetoothis in both entitlement files. - If the permission prompt was previously denied, reset in System Settings → Privacy & Security → Bluetooth.
- Confirm
- Windows — scan returns nothing — Pair the printer first in Windows Bluetooth settings.
- Linux — permission denied — Add your user to the
bluetoothgroup:sudo usermod -aG bluetooth $USER(re-login required). - BLE printer not detected on desktop — Power-cycle the printer; some models only broadcast BLE when not connected via Classic BT.
- Unicode / Indian language issues — Ensure
TextEncoding.utf8is set. If the printer lacks Indic font ROM, characters will render as boxes regardless of encoding. - Rupee symbol (₹) not showing — Printer must support Unicode currency symbols; not all thermal firmware does.
Support #
- YouTube tutorials: youtube.com/SnippetCoder
- Email: snippetcoder@outlook.com
License #
This project is licensed under the MIT License.