flutter_feature_printer 0.0.1
flutter_feature_printer: ^0.0.1 copied to clipboard
Flutter library for handle printer (thermal, edc, etc)
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_feature_printer/esc_pos_utils_plus.dart';
import 'package:flutter_feature_printer/flutter_feature_printer.dart';
import 'package:flutter_feature_printer_example/data/dto/model/feature_model.dart';
import 'presentation/widget/feature_widget.dart';
import 'package:image/image.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Feature Printer',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(title: 'Flutter Feature Printer'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
late FeatureThermalPrinterRepository thermalPrinter;
List<FeatureModel> features = [
FeatureModel(
title: 'Is Bluetooth Permission Granted',
desc: 'Check whether bluetooth permission granted',
key: 'IS_BLUETOOTH_PERMISSION_GRANTED',
),
FeatureModel(
title: 'Is Bluetooth Enabled',
desc: 'Check whether bluetooth enabled',
key: 'IS_BLUETOOTH_ENABLED',
),
FeatureModel(
title: 'Check Printer Connection Status',
desc: 'Check Printer Connection Status',
key: 'CHECK_CONNECTION_STATUS',
),
FeatureModel(
title: 'Check List Paired Bluetooth',
desc: 'Check List Paired Bluetooth',
key: 'LIST_PAIRED_BLUETOOTH',
),
FeatureModel(
title: 'Check Connected Mac Address Printer',
desc: 'Check Connected Mac Address Printer',
key: 'CONNECTED_PRINTER_MAC_ADDRESS',
),
FeatureModel(
title: 'Connect With Printer Thermal',
desc: 'Connect With Printer Thermal',
key: 'CONNECT',
),
FeatureModel(
title: 'Disconnect With Printer Thermal',
desc: 'Disconnect With Printer Thermal',
key: 'DISCONNECT',
),
FeatureModel(
title: 'Print Using Bytes',
desc: 'Print Using Bytes',
key: 'PRINT_USING_BYTES',
),
FeatureModel(
title: 'Print Asset Image',
desc: 'Print Asset Image',
key: 'PRINT_ASSET_IMAGE',
),
];
@override
void initState() {
super.initState();
thermalPrinter = FeatureThermalPrinter();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Biometric')),
body: ListView.builder(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
itemCount: features.length,
itemBuilder: (_, index) {
final feature = features[index];
return GestureDetector(
onTap: () async {
switch (feature.key) {
case "IS_BLUETOOTH_PERMISSION_GRANTED":
final isBluetoothPermissionGranted = await thermalPrinter.isBluetoothPermissionGranted;
log("is bluetooth permission granted: $isBluetoothPermissionGranted");
break;
case "IS_BLUETOOTH_ENABLED":
final isBluetoothEnabled = await thermalPrinter.isBluetoothEnabled;
log("is bluetooth enabled: $isBluetoothEnabled");
break;
case "CHECK_CONNECTION_STATUS":
final isConnected = await thermalPrinter.isConnectedToPrinter;
log("is connected: $isConnected");
break;
case "LIST_PAIRED_BLUETOOTH":
final pairedBluetooth = await thermalPrinter.pairedBluetoothDevices;
log("total paired bluetooth: ${pairedBluetooth.length}");
for (final info in pairedBluetooth) {
log("bluetooh info: ${info.name}, mac address: ${info.macAdress}");
}
break;
case "CONNECTED_PRINTER_MAC_ADDRESS":
final macAddress = thermalPrinter.connectedMacAddress;
log("connected mac address printer: $macAddress");
break;
case "CONNECT":
final isConnected = await thermalPrinter.connect(macPrinterAddress: "DC:0D:51:F5:7E:AD");
log("is connected: $isConnected");
break;
case "DISCONNECT":
final isConnected = await thermalPrinter.disconnect();
log("is connected: $isConnected");
break;
case "PRINT_USING_BYTES":
final content = await customContent();
final result = await thermalPrinter.printBytes(content);
log("result: $result");
break;
case "PRINT_ASSET_IMAGE":
final content = await assetImage();
thermalPrinter.printBytes(content);
break;
}
},
child: ItemFeatureWidget(feature: feature),
);
},
),
);
}
Future<List<int>> getDummyByteForPrint() async {
final generator = await thermalPrinter.createGenerator(paperSize: PaperSize.mm58);
List<int> bytes = [];
bytes += generator.text('Regular: aA bB cC dD eE fF gG hH iI jJ kK lL mM nN oO pP qQ rR sS tT uU vV wW xX yY zZ');
bytes += generator.text('Special 1: àÀ èÈ éÉ ûÛ üÜ çÇ ôÔ', styles: const PosStyles(codeTable: 'CP1252'));
bytes += generator.text('Special 2: blåbærgrød', styles: const PosStyles(codeTable: 'CP1252'));
bytes += generator.text('Bold text', styles: const PosStyles(bold: true));
bytes += generator.text('Reverse text', styles: const PosStyles(reverse: true));
bytes += generator.text('Underlined text', styles: const PosStyles(underline: true), linesAfter: 1);
bytes += generator.text('Align left', styles: const PosStyles(align: PosAlign.left));
bytes += generator.text('Align center', styles: const PosStyles(align: PosAlign.center));
bytes += generator.text('Align right', styles: const PosStyles(align: PosAlign.right), linesAfter: 1);
bytes += generator.row([
PosColumn(
text: 'col3',
width: 3,
styles: const PosStyles(align: PosAlign.center, underline: true),
),
PosColumn(
text: 'col6',
width: 6,
styles: const PosStyles(align: PosAlign.center, underline: true),
),
PosColumn(
text: 'col3',
width: 3,
styles: const PosStyles(align: PosAlign.center, underline: true),
),
]);
bytes += generator.text('Text size 200%',
styles: const PosStyles(
height: PosTextSize.size2,
width: PosTextSize.size2,
));
// Print barcode
final List<int> barData = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 4];
bytes += generator.barcode(Barcode.upcA(barData));
bytes += generator.feed(2);
bytes += generator.cut();
return bytes;
}
Future<List<int>> customContent() async {
final generator = await thermalPrinter.createGenerator(paperSize: PaperSize.mm58);
List<int> bytes = [];
bytes += generator.text(
'Taufik Fadlurahman Fajari',
styles: PosStyles(
align: PosAlign.center,
),
);
bytes += generator.text(
'+6281283602320',
styles: PosStyles(
align: PosAlign.center,
),
);
bytes += generator.text(
'[email protected]',
styles: PosStyles(
align: PosAlign.center,
),
);
bytes += generator.text(
'Jakarta Selatan, Indonesia',
styles: PosStyles(
align: PosAlign.center,
),
);
bytes += generator.feed(1);
bytes += generator.hr(ch: "=");
bytes += generator.feed(1);
bytes += generator.row([
PosColumn(
text: '1',
width: 1,
styles: const PosStyles(align: PosAlign.center, underline: true),
),
PosColumn(
text: 'Ayam Madura',
width: 8,
styles: const PosStyles(align: PosAlign.left, underline: true),
),
PosColumn(
text: '28.000',
width: 3,
styles: const PosStyles(align: PosAlign.center, underline: true),
),
]);
bytes += generator.row([
PosColumn(
text: '1',
width: 1,
styles: const PosStyles(align: PosAlign.center, underline: true),
),
PosColumn(
text: 'Nasi Goreng',
width: 8,
styles: const PosStyles(align: PosAlign.left, underline: true),
),
PosColumn(
text: '15.000',
width: 3,
styles: const PosStyles(align: PosAlign.center, underline: true),
),
]);
bytes += generator.row([
PosColumn(
text: '1',
width: 1,
styles: const PosStyles(align: PosAlign.center, underline: true),
),
PosColumn(
text: 'Thai Tea',
width: 8,
styles: const PosStyles(align: PosAlign.left, underline: true),
),
PosColumn(
text: '22.000',
width: 3,
styles: const PosStyles(align: PosAlign.center, underline: true),
),
]);
bytes += generator.row([
PosColumn(
text: '1',
width: 1,
styles: const PosStyles(align: PosAlign.center, underline: true),
),
PosColumn(
text: 'Es Tebu',
width: 8,
styles: const PosStyles(align: PosAlign.left, underline: true),
),
PosColumn(
text: '16.000',
width: 3,
styles: const PosStyles(align: PosAlign.center, underline: true),
),
]);
bytes += generator.hr();
bytes += generator.row([
PosColumn(
text: ' ',
width: 1,
styles: const PosStyles(align: PosAlign.center),
),
PosColumn(
text: 'Total',
width: 8,
styles: const PosStyles(align: PosAlign.left, underline: true),
),
PosColumn(
text: '81.000',
width: 3,
styles: const PosStyles(align: PosAlign.center, underline: true, bold: true),
),
]);
bytes += generator.feed(1);
bytes += generator.hr();
bytes += generator.text(
'T H A N K Y O U',
styles: PosStyles(
align: PosAlign.center,
),
);
bytes += generator.feed(1);
bytes += generator.qrcode(
'https://www.linkedin.com/in/taufikfadlurahmanfajari/',
align: PosAlign.center,
);
bytes += generator.feed(1);
bytes += generator.cut();
return bytes;
}
Future<List<int>> assetImage() async {
final generator = await thermalPrinter.createGenerator(paperSize: PaperSize.mm58);
List<int> bytes = [];
final assetImage = await rootBundle.load('images/flutter_logo.png');
final imageBytes = assetImage.buffer.asUint8List();
final originalImage = decodeImage(imageBytes);
final double aspectRatio = originalImage!.width / originalImage.height;
final int newHeight = (240 / aspectRatio).round();
final resizedImage = copyResize(
originalImage,
width: 240,
height: newHeight,
interpolation: Interpolation.linear,
);
final grayscaleImg = grayscale(resizedImage);
final bwImage = contrast(grayscaleImg, contrast: 50);
bytes += generator.image(bwImage);
bytes += generator.cut();
return bytes;
}
}