thermal_printer_flutter 2.0.0
thermal_printer_flutter: ^2.0.0 copied to clipboard
A Flutter plugin for thermal printing supporting Bluetooth, USB, and Network printers across Android, iOS, macOS, Windows, Linux, and Web platforms. Easy to use and integrates with esc_pos_utils for g [...]
thermal_printer_flutter #
Flutter plugin for ESC/POS thermal printing over USB, Bluetooth (BLE) and Network (TCP/IP) on Android, iOS, macOS, Windows, Linux and Web.
Platform support #
| Platform | USB | Bluetooth | Network |
|---|---|---|---|
| Android | ❌ | ✅ | ✅ |
| iOS | ❌ | ✅ | ✅ |
| macOS | ✅ | ✅ | ✅ |
| Windows | ✅ | ✅ | ✅ |
| Linux | ❌ | ❌ | ✅ |
| Web | ❌ | ❌ | 🚧 |
Install #
dependencies:
thermal_printer_flutter: ^0.1.0
import 'package:thermal_printer_flutter/thermal_printer_flutter.dart';
Permissions & setup per platform #
Android #
Add to android/app/src/main/AndroidManifest.xml:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
Android 12+ also needs:
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
iOS #
Add to ios/Runner/Info.plist:
<key>NSBluetoothAlwaysUsageDescription</key>
<string>We need Bluetooth access to connect to thermal printers</string>
<key>NSBluetoothPeripheralUsageDescription</key>
<string>We need Bluetooth access to connect to thermal printers</string>
iOS 13+ also needs:
<key>NSBluetoothAlwaysAndWhenInUseUsageDescription</key>
<string>We need Bluetooth access to connect to thermal printers</string>
macOS #
Add the Bluetooth keys to macos/Runner/Info.plist:
<key>NSBluetoothAlwaysUsageDescription</key>
<string>We need Bluetooth access to connect to thermal printers</string>
<key>NSBluetoothPeripheralUsageDescription</key>
<string>We need Bluetooth access to connect to thermal printers</string>
Add the entitlements to both macos/Runner/DebugProfile.entitlements and macos/Runner/Release.entitlements:
<key>com.apple.security.device.bluetooth</key>
<true/>
<key>com.apple.security.print</key>
<true/>
USB on macOS goes through the system print queue (CUPS), not raw USB. Add the printer in System Settings → Printers & Scanners first (the Generic driver works for most ESC/POS printers).
getPrinters(printerType: PrinterType.usb)then lists the installed queues.
Windows #
No manifest permissions required. Install the USB printer driver so it shows up in the Windows print spooler. (Bluetooth is not supported on Windows.)
Linux #
Network only — make sure the firewall allows the printer port (default 9100).
Web #
Experimental. Network printing requires a server/proxy that accepts the connection (raw TCP sockets aren't available in the browser).
Usage #
final printer = ThermalPrinterFlutter();
List printers #
final usb = await printer.getPrinters(printerType: PrinterType.usb); // Windows, macOS
final bluetooth = await printer.getPrinters(printerType: PrinterType.bluetooth); // Android, iOS, macOS
Discover network printers #
final found = await printer.discoverNetworkPrinters(
onProgress: (p) => print(p),
requireConfirmation: true, // optional: probe port 9100 (ESC/POS) to drop false positives
);
Or add one manually:
final p = Printer(type: PrinterType.network, name: 'Kitchen', ip: '192.168.1.50', port: '9100');
Connect (Bluetooth / Network) #
await printer.connect(printer: target);
await printer.disconnect(printer: target);
USB printers are connectionless — no
connect()needed.
Print #
final generator = Generator(PaperSize.mm80, await CapabilityProfile.load());
final bytes = <int>[]
..addAll(generator.text('Hello', styles: const PosStyles(align: PosAlign.center, bold: true)))
..addAll(generator.feed(2))
..addAll(generator.cut());
await printer.printBytes(bytes: bytes, printer: target);
// Multiple copies in a single job (do not call printBytes in a loop):
await printer.printBytes(bytes: bytes, printer: target, copies: 2);
Print a widget / image #
final image = await printer.screenShotWidget(
context,
widget: MyReceipt(),
width: 576, // 80 mm @ 203 dpi (use 384 for 58 mm)
pixelRatio: 4.0,
dither: true, // Floyd–Steinberg (default) — best for logos/photos
);
final bytes = <int>[]
..addAll(generator.imageRaster(image))
..addAll(generator.cut());
await printer.printBytes(bytes: bytes, printer: target);
Printer status (USB) #
final status = await printer.getPrinterStatus(printer: target);
print('${status.description} (paperOut=${status.isPaperOut}, offline=${status.isOffline})');
Release resources #
await printer.dispose(); // closes pooled network sockets
Notes & limitations #
getPrinterStatusreturns real data only for USB printers on Windows (spooler) and macOS (CUPS); otherwisePrinterStatus.unknown.isConnectedis alwaystruefor USB (connectionless) — usegetPrinterStatusfor real health.- Bluetooth manages a single active connection;
disconnect()closes the active one regardless of thePrinterpassed. - Network discovery flags any host with an open port (9100/515/631) as a candidate — use
requireConfirmation: trueto reduce false positives.
License #
MIT — see LICENSE.