dopos_print 0.0.9 copy "dopos_print: ^0.0.9" to clipboard
dopos_print: ^0.0.9 copied to clipboard

***** EASY TO USE ***** The dopos_print plugin is a Flutter plugin designed to interface with thermal printers on Windows and Android (Bluetooth printers). This plugin enables Flutter applications to [...]

example/lib/main.dart

import 'dart:convert';
import 'dart:developer';

import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:io';
import 'package:flutter/services.dart';
import 'package:path_provider/path_provider.dart';
import 'package:dopos_print/dopos_print.dart';
import 'package:permission_handler/permission_handler.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  // Request Bluetooth permissions
  await _requestBluetoothPermission();
  runApp(const MyApp());
}

Future<void> _requestBluetoothPermission() async {
  if (Platform.isAndroid) {
    await _requestBluetoothPermissions();
    await _requestLocationPermission();
  }
}

Future<void> _requestBluetoothPermissions() async {
  PermissionStatus bluetoothScanPermission =
      await Permission.bluetoothScan.request();
  PermissionStatus bluetoothConnectPermission =
      await Permission.bluetoothConnect.request();

  if (bluetoothScanPermission.isGranted &&
      bluetoothConnectPermission.isGranted) {
    print("Bluetooth permissions granted");
  } else {
    print("Bluetooth permissions denied");
    if (bluetoothScanPermission.isPermanentlyDenied ||
        bluetoothConnectPermission.isPermanentlyDenied) {
      openAppSettings();
    }
  }
}

Future<void> _requestLocationPermission() async {
  PermissionStatus locationPermission =
      await Permission.locationWhenInUse.request();

  if (locationPermission.isGranted) {
    print("Location permission granted");
  } else if (locationPermission.isDenied) {
    print("Location permission denied");
  } else if (locationPermission.isPermanentlyDenied) {
    openAppSettings();
  }
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final DoposPrint _doposPrintPlugin = DoposPrint();
  List<Map<String, String>> _printers = [];
  String _jsonInput = '';
  String? _selectedPrinter;

  late Map<String, dynamic> _SAMPLE_JSON_INSTRUCTION_;
  TextEditingController _jsonD = TextEditingController();

  @override
  void initState() {
    super.initState();
    _checkPermissions();
  }

  Future<void> _checkPermissions() async {
    if (await Permission.bluetoothConnect.request().isGranted) {
      await _preparePrintInstructions();
      _jsonD.text = jsonEncode(_SAMPLE_JSON_INSTRUCTION_).toString();
      _loadPrinters();
    } else {
      // Handle permission denial gracefully
      print('Bluetooth/Storage permission denied!');
    }
  }

  Future<void> _preparePrintInstructions() async {
    final imagePath = await _loadImageFromAssets('assets/images/image.png');
    _SAMPLE_JSON_INSTRUCTION_ = {
      "startX": 0,
      "startY": 0,
      "data": [
        {
          "startX": 0,
          "endX": 100,
          "lineSpacing": 0,
          "imagePath": imagePath,
          "imageWidth": 100,
          "imageHeight": 35,
          "align": "center",
          "isNewLine": true
        },
        {
          "startX": 0,
          "endX": 100,
          "text": " ",
          "fontSize": 8,
          "fontWeight": "Normal",
          "lineSpacing": 0,
          "align": "center",
          "isNewLine": true
        },
        {
          "startX": 0,
          "endX": 100,
          "text": "DANGAPARA, SULTANPUR, BURDWAN",
          "fontSize": 8,
          "fontWeight": "Normal",
          "lineSpacing": 0,
          "align": "center",
          "isNewLine": true
        },
        {
          "startX": 0,
          "endX": 100,
          "text": "Phone: 8765346533",
          "fontSize": 8,
          "fontWeight": "Normal",
          "lineSpacing": 0,
          "align": "center",
          "isNewLine": true
        },
        {
          "startX": 0,
          "endX": 100,
          "text": "GSTIN: ",
          "fontSize": 8,
          "fontWeight": "Normal",
          "lineSpacing": 0,
          "align": "center",
          "isNewLine": true
        },
        {
          "startX": 0,
          "endX": 100,
          "text": "................................",
          "fontSize": 8,
          "fontWeight": "Bold",
          "lineSpacing": 0,
          "align": "center",
          "isNewLine": true
        },
        {
          "startX": 0,
          "endX": 100,
          "text": " ",
          "fontSize": 8,
          "fontWeight": "Normal",
          "lineSpacing": 0,
          "align": "center",
          "isNewLine": true
        },
        {
          "startX": 0,
          "endX": 100,
          "text": "TAX INVOICE",
          "fontSize": 10,
          "fontWeight": "Normal",
          "lineSpacing": 0,
          "align": "center",
          "isNewLine": true
        },
        {
          "startX": 0,
          "endX": 100,
          "text": " ",
          "fontSize": 8,
          "fontWeight": "Normal",
          "lineSpacing": 0,
          "align": "center",
          "isNewLine": true
        },
        {
          "startX": 0,
          "endX": 50,
          "text": "Date: 15/08/24",
          "fontSize": 8,
          "fontWeight": "Normal",
          "lineSpacing": 0,
          "align": "left",
          "isNewLine": false
        },
        {
          "startX": 50,
          "endX": 100,
          "text": "Time: 09:58:09",
          "fontSize": 8,
          "fontWeight": "Normal",
          "lineSpacing": 0,
          "align": "right",
          "isNewLine": true
        },
        {
          "startX": 0,
          "endX": 100,
          "text": "Bill No.: D9S1O0004",
          "fontSize": 8,
          "fontWeight": "Normal",
          "lineSpacing": 0,
          "align": "left",
          "isNewLine": true
        },
        {
          "startX": 0,
          "endX": 100,
          "text": "................................",
          "fontSize": 8,
          "fontWeight": "Bold",
          "lineSpacing": 0,
          "align": "center",
          "isNewLine": true
        },
        {
          "startX": 0,
          "endX": 15,
          "text": "Sl.",
          "fontSize": 8,
          "fontWeight": "Normal",
          "lineSpacing": 0,
          "align": "left",
          "isNewLine": false
        },
        {
          "startX": 15,
          "endX": 68,
          "text": "ITEM",
          "fontSize": 8,
          "fontWeight": "Normal",
          "lineSpacing": 0,
          "align": "left",
          "isNewLine": false
        },
        {
          "startX": 71,
          "endX": 100,
          "text": "MRP",
          "fontSize": 8,
          "fontWeight": "Normal",
          "lineSpacing": 0,
          "align": "right",
          "isNewLine": true
        },
        {
          "startX": 0,
          "endX": 25,
          "text": "RATE",
          "fontSize": 8,
          "fontWeight": "Normal",
          "lineSpacing": 0,
          "align": "right",
          "isNewLine": false
        },
        {
          "startX": 25,
          "endX": 50,
          "text": "QTY",
          "fontSize": 8,
          "fontWeight": "Normal",
          "lineSpacing": 0,
          "align": "right",
          "isNewLine": false
        },
        {
          "startX": 50,
          "endX": 75,
          "text": "TAX%",
          "fontSize": 8,
          "fontWeight": "Normal",
          "lineSpacing": 0,
          "align": "right",
          "isNewLine": false
        },
        {
          "startX": 75,
          "endX": 100,
          "text": "TOTAL",
          "fontSize": 8,
          "fontWeight": "Bold",
          "lineSpacing": 0,
          "align": "right",
          "isNewLine": true
        },
        {
          "startX": 0,
          "endX": 100,
          "text": "................................",
          "fontSize": 8,
          "fontWeight": "Bold",
          "lineSpacing": 0,
          "align": "center",
          "isNewLine": true
        },
        {
          "startX": 0,
          "endX": 15,
          "text": "1.",
          "fontSize": 8,
          "fontWeight": "Normal",
          "lineSpacing": 0,
          "align": "left",
          "isNewLine": false
        },
        {
          "startX": 15,
          "endX": 68,
          "text": "RACIRAFT SYRUP 250ML.",
          "fontSize": 8,
          "fontWeight": "Normal",
          "lineSpacing": 0,
          "align": "left",
          "isNewLine": false
        },
        {
          "startX": 70,
          "endX": 100,
          "text": "215.00",
          "fontSize": 8,
          "fontWeight": "Normal",
          "lineSpacing": 0,
          "align": "right",
          "isNewLine": true
        },
        {
          "startX": 0,
          "endX": 25,
          "text": "182.20",
          "fontSize": 8,
          "fontWeight": "Normal",
          "lineSpacing": 0,
          "align": "right",
          "isNewLine": false
        },
        {
          "startX": 25,
          "endX": 50,
          "text": "1.000",
          "fontSize": 8,
          "fontWeight": "Normal",
          "lineSpacing": 0,
          "align": "right",
          "isNewLine": false
        },
        {
          "startX": 50,
          "endX": 75,
          "text": "18.00",
          "fontSize": 8,
          "fontWeight": "Normal",
          "lineSpacing": 0,
          "align": "right",
          "isNewLine": false
        },
        {
          "startX": 75,
          "endX": 100,
          "text": "215.00",
          "fontSize": 8,
          "fontWeight": "Bold",
          "lineSpacing": 0,
          "align": "right",
          "isNewLine": true
        },
        {
          "startX": 0,
          "endX": 100,
          "text": "................................",
          "fontSize": 8,
          "fontWeight": "Bold",
          "lineSpacing": 0,
          "align": "center",
          "isNewLine": true
        },
        {
          "startX": 0,
          "endX": 40,
          "text": "Total",
          "fontSize": 8,
          "fontWeight": "Normal",
          "lineSpacing": 0,
          "align": "left",
          "isNewLine": false
        },
        {
          "startX": 40,
          "endX": 100,
          "text": "215.00",
          "fontSize": 8,
          "fontWeight": "Normal",
          "lineSpacing": 0,
          "align": "right",
          "isNewLine": true
        },
        {
          "startX": 0,
          "endX": 40,
          "text": "Tax Amt.",
          "fontSize": 8,
          "fontWeight": "Normal",
          "lineSpacing": 0,
          "align": "left",
          "isNewLine": false
        },
        {
          "startX": 40,
          "endX": 100,
          "text": "32.80",
          "fontSize": 8,
          "fontWeight": "Normal",
          "lineSpacing": 0,
          "align": "right",
          "isNewLine": true
        },
        {
          "startX": 0,
          "endX": 40,
          "text": "Round off",
          "fontSize": 8,
          "fontWeight": "Normal",
          "lineSpacing": 0,
          "align": "left",
          "isNewLine": false
        },
        {
          "startX": 40,
          "endX": 100,
          "text": "0.00",
          "fontSize": 8,
          "fontWeight": "Normal",
          "lineSpacing": 0,
          "align": "right",
          "isNewLine": true
        },
        {
          "startX": 0,
          "endX": 100,
          "text": " ",
          "fontSize": 10,
          "fontWeight": "Bold",
          "lineSpacing": 0,
          "align": "center",
          "isNewLine": true
        },
        {
          "startX": 0,
          "endX": 100,
          "text": "Net Payable:  215",
          "fontSize": 10,
          "fontWeight": "Bold",
          "lineSpacing": 0,
          "align": "center",
          "isNewLine": true
        },
        {
          "startX": 0,
          "endX": 100,
          "text": " ",
          "fontSize": 10,
          "fontWeight": "Bold",
          "lineSpacing": 0,
          "align": "center",
          "isNewLine": true
        },
        {
          "startX": 0,
          "endX": 100,
          "text": "ITEM(S)/QTY: 1/1.000",
          "fontSize": 8,
          "fontWeight": "Normal",
          "lineSpacing": 0,
          "align": "left",
          "isNewLine": true
        },
        {
          "startX": 0,
          "endX": 100,
          "text": "TOTAL INCL. OF ALL GST TAX.",
          "fontSize": 8,
          "fontWeight": "Normal",
          "lineSpacing": 0,
          "align": "left",
          "isNewLine": true
        },
        {
          "startX": 0,
          "endX": 100,
          "text": "********************************",
          "fontSize": 8,
          "fontWeight": "Normal",
          "lineSpacing": 0,
          "align": "center",
          "isNewLine": true
        },
        {
          "startX": 0,
          "endX": 50,
          "text": "TAX%",
          "fontSize": 8,
          "fontWeight": "Normal",
          "lineSpacing": 0,
          "align": "left",
          "isNewLine": false
        },
        {
          "startX": 50,
          "endX": 100,
          "text": "TAXABLE",
          "fontSize": 8,
          "fontWeight": "Normal",
          "lineSpacing": 0,
          "align": "right",
          "isNewLine": true
        },
        {
          "startX": 0,
          "endX": 33,
          "text": "CGST",
          "fontSize": 8,
          "fontWeight": "Normal",
          "lineSpacing": 0,
          "align": "right",
          "isNewLine": false
        },
        {
          "startX": 33,
          "endX": 63,
          "text": "SGST",
          "fontSize": 8,
          "fontWeight": "Normal",
          "lineSpacing": 0,
          "align": "right",
          "isNewLine": false
        },
        {
          "startX": 65,
          "endX": 100,
          "text": "TAX AMT",
          "fontSize": 8,
          "fontWeight": "Normal",
          "lineSpacing": 0,
          "align": "right",
          "isNewLine": true
        },
        {
          "startX": 0,
          "endX": 100,
          "text": "................................",
          "fontSize": 8,
          "fontWeight": "Bold",
          "lineSpacing": 0,
          "align": "center",
          "isNewLine": true
        },
        {
          "startX": 0,
          "endX": 50,
          "text": "18.0%",
          "fontSize": 8,
          "fontWeight": "Normal",
          "lineSpacing": 0,
          "align": "left",
          "isNewLine": false
        },
        {
          "startX": 50,
          "endX": 100,
          "text": "182.20",
          "fontSize": 8,
          "fontWeight": "Normal",
          "lineSpacing": 0,
          "align": "right",
          "isNewLine": true
        },
        {
          "startX": 0,
          "endX": 33,
          "text": "16.40",
          "fontSize": 8,
          "fontWeight": "Normal",
          "lineSpacing": 0,
          "align": "right",
          "isNewLine": false
        },
        {
          "startX": 33,
          "endX": 64,
          "text": "16.40",
          "fontSize": 8,
          "fontWeight": "Normal",
          "lineSpacing": 0,
          "align": "right",
          "isNewLine": false
        },
        {
          "startX": 65,
          "endX": 100,
          "text": "32.80",
          "fontSize": 8,
          "fontWeight": "Normal",
          "lineSpacing": 0,
          "align": "right",
          "isNewLine": true
        },
        {
          "startX": 0,
          "endX": 100,
          "text": "********************************",
          "fontSize": 8,
          "fontWeight": "Normal",
          "lineSpacing": 0,
          "align": "center",
          "isNewLine": true
        },
        {
          "startX": 0,
          "endX": 100,
          "text": "YOU SAVED:  0.00",
          "fontSize": 10,
          "fontWeight": "Bold",
          "lineSpacing": 0,
          "align": "center",
          "isNewLine": true
        },
        {
          "startX": 0,
          "endX": 100,
          "text": "********************************",
          "fontSize": 8,
          "fontWeight": "Normal",
          "lineSpacing": 0,
          "align": "center",
          "isNewLine": true
        },
        {
          "startX": 0,
          "endX": 60,
          "text": "Payment Mode:",
          "fontSize": 8,
          "fontWeight": "Normal",
          "lineSpacing": 0,
          "align": "left",
          "isNewLine": false
        },
        {
          "startX": 60,
          "endX": 100,
          "text": "CASH",
          "fontSize": 8,
          "fontWeight": "Bold",
          "lineSpacing": 0,
          "align": "right",
          "isNewLine": true
        },
        {
          "startX": 0,
          "endX": 60,
          "text": "CASH:",
          "fontSize": 8,
          "fontWeight": "Normal",
          "lineSpacing": 0,
          "align": "left",
          "isNewLine": false
        },
        {
          "startX": 60,
          "endX": 100,
          "text": "215.00",
          "fontSize": 8,
          "fontWeight": "Normal",
          "lineSpacing": 0,
          "align": "right",
          "isNewLine": true
        },
        {
          "startX": 0,
          "endX": 100,
          "text": "................................",
          "fontSize": 8,
          "fontWeight": "Bold",
          "lineSpacing": 0,
          "align": "center",
          "isNewLine": true
        },
        {
          "startX": 0,
          "endX": 100,
          "text": "Thank You, Visit again!!!",
          "fontSize": 8,
          "fontWeight": "Normal",
          "lineSpacing": 0,
          "align": "center",
          "isNewLine": true
        }
      ]
    };

    setState(() {});
  }

  Future<String> _loadImageFromAssets(String assetPath) async {
    final byteData = await rootBundle.load(assetPath);
    final tempDir = await getTemporaryDirectory();
    final file = File('${tempDir.path}/image.png');
    await file.writeAsBytes(byteData.buffer.asUint8List(), flush: true);
    return file.path;
  }

  Future<void> _loadPrinters() async {
    try {
      final printers = await _doposPrintPlugin.listPrinters();
      setState(() {
        _printers = printers;
      });
    } catch (e) {
      log('Failed to load printers: $e');
    }
  }

  Future<void> _print() async {
    if (_selectedPrinter == null) {
      log('No printer selected.');
      return;
    }

    _jsonInput = _jsonD.text;

    if (_jsonInput.isEmpty) {
      log('Please enter JSON data.');
      return;
    }

    try {
      final tempDir = await getTemporaryDirectory();
      final tempFile = File('${tempDir.path}/printInstructions.json');
      await tempFile.writeAsString(_jsonInput);

      await _doposPrintPlugin.print(
        int.parse(_selectedPrinter!),
        tempFile.path,
      );
      log('Print command sent successfully.');
    } on PlatformException catch (e) {
      log('Failed to send print command: ${e.message}');
    } catch (e) {
      log('Error: $e');
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Printer App',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Printer App'),
        ),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              SizedBox(height: 20),
              if (_printers.isNotEmpty)
                Padding(
                    padding: const EdgeInsets.symmetric(horizontal: 16.0),
                    child: DropdownButton<String>(
                      hint: const Text('Select Printer'),
                      value: _selectedPrinter,
                      onChanged: (String? newValue) {
                        setState(() {
                          _selectedPrinter = newValue;
                        });
                      },
                      items: _printers.map((printer) {
                        final printerIndex = printer.keys.first;
                        final printerName = printer.values.first;
                        log("$printerIndex===>$printerName");
                        return DropdownMenuItem<String>(
                          value: printerIndex, // Ensure printerIndex is unique
                          child: Row(
                            children: <Widget>[
                              const Icon(Icons.print),
                              const SizedBox(width: 10),
                              Text(printerName),
                            ],
                          ),
                        );
                      }).toList(),
                    )),
              SizedBox(height: 20),
              Padding(
                padding: const EdgeInsets.symmetric(horizontal: 16.0),
                child: TextField(
                  controller: _jsonD,
                  maxLines: 10,
                  decoration: const InputDecoration(
                    border: OutlineInputBorder(),
                    labelText: 'Enter JSON Data',
                  ),
                  // onChanged: (value) {
                  //   setState(() {
                  //     _jsonInput = value;
                  //   });
                  // },
                ),
              ),
              SizedBox(height: 20),
              ElevatedButton(
                onPressed: _print,
                child: const Text('Print'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
2
likes
0
points
44
downloads

Publisher

unverified uploader

Weekly Downloads

***** EASY TO USE ***** The dopos_print plugin is a Flutter plugin designed to interface with thermal printers on Windows and Android (Bluetooth printers). This plugin enables Flutter applications to list available thermal printers and send print jobs to a selected printer. The plugin supports printing text and images using JSON-formatted print instructions, allowing for flexible and customizable print layouts. It leverages the native Windows (c# and c++) and Android (JAVA).

Homepage

License

unknown (license)

Dependencies

flutter

More

Packages that depend on dopos_print