Git Product home page Git Product logo

esc_pos_utils's Introduction

esc_pos_utils

Pub Version

Base Flutter/Dart classes for ESC/POS printing. Generator class generates ESC/POS commands that can be sent to a thermal printer.

This is the "base" library that used for:

Main Features

  • Connect to Wi-Fi / Ethernet printers
  • Simple text printing using text method
  • Tables printing using row method
  • Text styling:
    • size, align, bold, reverse, underline, different fonts, turn 90°
  • Print images
  • Print barcodes
    • UPC-A, UPC-E, JAN13 (EAN13), JAN8 (EAN8), CODE39, ITF (Interleaved 2 of 5), CODABAR (NW-7), CODE128
  • Paper cut (partial, full)
  • Beeping (with different duration)
  • Paper feed, reverse feed

Note: Your printer may not support some of the presented features (some styles, partial/full paper cutting, reverse feed, barcodes...).

Generate a Ticket

Simple ticket with styles:

List<int> testTicket() {
  final List<int> bytes = [];
  // Using default profile
  final profile = await CapabilityProfile.load();
  final generator = Generator(PaperSize.mm80, profile);
  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: PosStyles(codeTable: PosCodeTable.westEur));
  bytes += generator.text('Special 2: blåbærgrød',
      styles: PosStyles(codeTable: PosCodeTable.westEur));

  bytes += generator.text('Bold text', styles: PosStyles(bold: true));
  bytes += generator.text('Reverse text', styles: PosStyles(reverse: true));
  bytes += generator.text('Underlined text',
      styles: PosStyles(underline: true), linesAfter: 1);
  bytes += generator.text('Align left', styles: PosStyles(align: PosAlign.left));
  bytes += generator.text('Align center', styles: PosStyles(align: PosAlign.center));
  bytes += generator.text('Align right',
      styles: PosStyles(align: PosAlign.right), linesAfter: 1);

  bytes += generator.text('Text size 200%',
      styles: PosStyles(
        height: PosTextSize.size2,
        width: PosTextSize.size2,
      ));

  bytes += generator.feed(2);
  bytes += generator.cut();
  return bytes;
}

Print a table row:

generator.row([
    PosColumn(
      text: 'col3',
      width: 3,
      styles: PosStyles(align: PosAlign.center, underline: true),
    ),
    PosColumn(
      text: 'col6',
      width: 6,
      styles: PosStyles(align: PosAlign.center, underline: true),
    ),
    PosColumn(
      text: 'col3',
      width: 3,
      styles: PosStyles(align: PosAlign.center, underline: true),
    ),
  ]);

Print an image:

This package implements 3 ESC/POS functions:

  • ESC * - print in column format
  • GS v 0 - print in bit raster format (obsolete)
  • GS ( L - print in bit raster format

Note that your printer may support only some of the above functions.

import 'dart:io';
import 'package:image/image.dart';

final ByteData data = await rootBundle.load('assets/logo.png');
final Uint8List bytes = data.buffer.asUint8List();
final Image image = decodeImage(bytes);
// Using `ESC *`
generator.image(image);
// Using `GS v 0` (obsolete)
generator.imageRaster(image);
// Using `GS ( L`
generator.imageRaster(image, imageFn: PosImageFn.graphics);

Print a Barcode:

final List<int> barData = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 4];
generator.barcode(Barcode.upcA(barData));

Print a QR Code:

Using native ESC/POS commands:

generator.qrcode('example.com');

To print a QR Code as an image (if your printer doesn't support native commands), add qr_flutter and path_provider as a dependency in your pubspec.yaml file.

String qrData = "google.com";
const double qrSize = 200;
try {
  final uiImg = await QrPainter(
    data: qrData,
    version: QrVersions.auto,
    gapless: false,
  ).toImageData(qrSize);
  final dir = await getTemporaryDirectory();
  final pathName = '${dir.path}/qr_tmp.png';
  final qrFile = File(pathName);
  final imgFile = await qrFile.writeAsBytes(uiImg.buffer.asUint8List());
  final img = decodeImage(imgFile.readAsBytesSync());

  generator.image(img);
} catch (e) {
  print(e);
}

Using Code Tables

Different printers support different sets of code tables. Some printer models are defined in CapabilityProfile class. So, if you want to change the default code table, it's important to choose the right profile:

// Xprinter XP-N160I
final profile = await CapabilityProfile.load('XP-N160I');
final generator = Generator(PaperSize.mm80, profile);
bytes += generator.setGlobalCodeTable('CP1252');

All available profiles can be retrieved by calling :

final profiles = await CapabilityProfile.getAvailableProfiles();

How to Help

  • Add a CapabilityProfile to support your printer's model. A new profile should be added to lib/resources/capabilities.json file
  • Test your printer and add it in the table: Wifi/Network printer or Bluetooth printer
  • Test and report bugs
  • Share your ideas about what could be improved (code optimization, new features...)

esc_pos_utils's People

Contributors

andrey-ushakov avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

esc_pos_utils's Issues

Chinese Code Page?

I am trying to print a receipt which contains Chinese words. (Generic Bluetooth thermal printer)
end up the Chinese character just become some weird symbol.
Is there a need to change the code page used by the printer? (Current CP850)

Rows with PosTextSize> size 1

ticket.row([
PosColumn(
text: "Licence Plate",
width: 6,
styles: PosStyles(align: PosAlign.right, width: PosTextSize.size2, height: PosTextSize.size2),
),
PosColumn(
text: 'AAA1111',
width: 6,
styles: PosStyles(align: PosAlign.left, width: PosTextSize.size2, height: PosTextSize.size2),
),
]);

column width is not correctly calculated if size is not PosTextSize.size1

Hebrew Characters not displaying Correctly

Hi,

I'm trying to display characters in Hebrew in some of my receipts, and although I'm encoding, it comes out as Chinese characters. Any way to print in a non-latin language?

 ticket.row([
        PosColumn(text: '${item.quantity}', width: 2),
        PosColumn(textEncoded: utf8.encode(item.menuItem.name), width: 10), //Where menu item is in hebrew
      ]);

version miss matching

facing version mismatching when I use esc_pos_printer&esc_pos_bluetooth at the same time..
any solution for it?

integrated printer

I see only comments for extenal printer
Can someone tell me if it works with integrated pos printer ?

Replacing obsolete GS v 0

Do you think replacing it with GS ( L is possible?
I tried to understand how the command should become but i find it too complex.
read these :
https://reference.epson-biz.com/modules/ref_escpos/index.php?content_id=98#gs_lparen_cl_fn50
https://reference.epson-biz.com/modules/ref_escpos/index.php?content_id=99#gs_lparen_cl_fn112
https://stackoverflow.com/questions/13715950/writing-a-bitmap-to-epson-tm88iv-through-esc-p-commands-write-to-nvram

The images print really slowly because they are being divided in many parts and printed individually right now. This should print it in one piece.

Request top margin parameters in qrcode printing

Hi, i have a mobile app in flutter that prints qrcodes using a bluetooth mobile printer.
i'm using these packages:
bluetooth_thermal_printer: ^0.0.4
esc_pos_utils: ^0.4.9

in the example codes for the ticket object, when i use ticket.qrcode(), the arguments are only (content,alignment,correction) and the qrcode is printed with a 13mm margin before the bluetooth printer starts printing the qrcode. Is there a way to adjust the top margin value (via arguments or parameters)? If not, may i request this additional parameters in qrcode printing?

Thanks.

ticker_qr_print

How To Print Barcode without text

How to print Barcode without text.
I´m using esc_pos_bluetooth: ^0.2.8

ticket.barcode(
Barcode.code39("123456-2-0001".split("")),
width: 1,
height: 120,
font: BarcodeFont.fontA,
align: PosAlign.left);

Sem título

PosColumn width (no wrapping)

Hi,

Great library, tested all the calls. Theres an issue with how PosColumn is handling width.

Although the columns specified, the print out does not wrap the within its "column width". Currently it prints all out in one line and for a very long text it'll just wrap the "complete" line rather than the text within the middle column.

ticket.row([
PosColumn(text: 'hello', width: 1),
PosColumn(text: 'a very very very very long text should wrap', width: 5)
PosColumn(text: 'final column', width: 6)
]

Thai printing issue

Thai character encoded with "cp874" PosCodeTable.thai_1&2 print result is unreadable

image

hr length issues

The NetworkPrinter doesn't pass the length along to the generator:

void hr({String ch = '-', int len, int linesAfter = 0}) {
    _socket.add(_generator.hr(ch: ch, linesAfter: linesAfter));
  }

And the length isn't calculated correctly. The length seems to depend on the previously used font, but hr always uses fontA. If the previous line uses fontB then the hr is too long:

List<int> hr({String ch = '-', int len, int linesAfter = 0}) {
    List<int> bytes = [];
    int n = len ?? _maxCharsPerLine ?? _getMaxCharsPerLine(_styles.fontType);
    String ch1 = ch.length == 1 ? ch : ch[0];
    bytes += text(List.filled(n, ch1).join(), linesAfter: linesAfter);
    return bytes;
  }

Setting the global font to fontA before hr helps, but then font changes in the style don't work so you need to set the global font for every font change:

printer.setGlobalFont(PosFontType.fontA);
printer.hr();

abstraction layer for pos printer ticket

Hi,

I am working on a package for scanning and persistent federated printing (bluetooth, network, star printers, brother label printers etc) of pos receipts using BLoC patterns (pos_printer_bloc)[https://github.com/apexlabs-ai/pos_printer_bloc] and I'm trying to base it on esc_pos_utils

One limitation I've come across is that I would like to have an abstraction layer between the ticket lines and the actual ESC representation.

I've now come up with this:

https://github.com/apexlabs-ai/pos_printer_bloc/blob/master/lib/src/pos_ticket_line.dart

and it would be good to have a constructor inside of esc_pos_utils Ticket.fromLines() to avoid the code duplication to go something like:

  Ticket _ticketFromLines(PaperSize paperSize, CapabilityProfile profile, {List <PosTicketLine> lines}) {
    final ticket = Ticket(paperSize, profile);
    for(var line in lines) {
      if(line is PosTicketText) {
        ticket.text(line.text, styles: line.styles, linesAfter: line.linesAfter);
      } else if(line is PosTicketRow) {
        ticket.row(line.cols);
      } else if(line is PosTicketBeep) {
        ticket.beep(n: line.n, duration: line.duration);
      } else if(line is PostTicketReset) {
        ticket.reset();
      } else if(line is PosTicketCut) {
        ticket.cut(mode: line.mode);
      } else if(line is PosTicketHr) {
        ticket.hr();
      } else if(line is PosTicketDrawer) {
        ticket.drawer(pin: line.pin);
      } else if(line is PosTicketFeed) {
        ticket.feed(line.lines);
      } else if(line is PosTicketImage) {
        ticket.image(line.image, align: line.align);
      } else if(line is PosTicketBarcode) {
        ticket.barcode(line.barcode,
            width: line.width,
            height: line.height,
            font: line.font,
            textPos: line.textPos,
            align: line.align
        );
      } else if(line is PosTicketQrcode) {
        ticket.qrcode(line.text, align: line.align,
            size: line.size,
            cor: line.correction);
      } else {
        print("_ticketFromLines: unsupported line type ${line.runtimeType}");
      }
    }
    return ticket;
  }

This would allow us to have similar methods for other printers, like:

  PrintCommands _commandsFromLines({List <PosTicketLine> lines}) {
    PrintCommands commands = PrintCommands();

    //    commands.appendEncoding(StarEncoding.UTF8);
    for(var line in lines) {
      if(line is PosTicketText) {
        commands.appendBitmapText(
            text: line.text,
            alignment:  _starAlignment[line.styles.align],
//            fontSize: line.styles.height.value,
//            width: line.styles.width.value
        );
      } else if(line is PosTicketCut) {
        commands.appendCutPaper(_starCutAction[line.mode]);
      } else if(line is PosTicketHr) {
        commands.appendBitmapText(text: '--------------------------------------');
      } else if(line is PosTicketFeed) {
        for (int i = 1; i < line.lines; i++) {
          commands.appendBitmapText(text: "\n\n");
        }
      } else {
        print("_commandsFromLines: unsupported line type ${line.runtimeType}");
      }
    }

Depends on esc_pos_utils ^0.3.6

Hello!
I got errors when install esc_pos_.

Here my packages:

esc_pos_utils: ^0.4.7
esc_pos_bluetooth: ^0.2.8
esc_pos_printer: ^3.2.7
flutter_bluetooth_basic: ^0.1.5

When I get package flutter pub get I got:

Because esc_pos_bluetooth >=0.2.8 depends on esc_pos_utils ^0.3.6 and ineonspm depends on esc_pos_utils ^0.4.7, esc_pos_bluetooth >=0.2.8 is forbidden.
So, because ineonspm depends on esc_pos_bluetooth ^0.2.8, version solving failed.

Chinese strings are not supported

icket.text('简体中文',
styles: PosStyles(
height: PosTextSize.size2,
width: PosTextSize.size2,
));
Invalid argument (string): Contains invalid characters.: "简体中文"

Special Character print issue.

Ca't print Special characters like currency symbol

like NumberFormat.simpleCurrency(name: 'INR').currencySymbol as String ₹

error:

[ERROR:flutter/lib/ui/ui_dart_state.cc(166)] Unhandled Exception: Invalid argument (string): Contains invalid characters.: "₹102.90"
E/flutter ( 1978): #0      _UnicodeSubsetEncoder.convert (dart:convert/ascii.dart:88:9)
E/flutter ( 1978): #1      Latin1Codec.encode (dart:convert/latin1.dart:42:46)
E/flutter ( 1978): #2      Ticket._encode (package:esc_pos_utils/src/ticket.dart:67:21)

Flutter 2 WiFi print issues

I am unable to print using network thermal printer Epson TM M30 after Flutter 2 update.
The app opens the Android Print option when the printing code is executed.

Standardised workflow for printer / library testing.

I would try to work out a standardised testing workflow, so that new printers and / or changes of the implemented features can be tested easily and repeatable.
I think issues could be tracked down faster with the information of some standard test.

I got this idea, because I am working with a thermal printer, that is not in the list of tested printers, but I don't know if I had tested everything, for example.
But I don't have unlimited access to this printer.
So it would have been nice to just fire up a test-app that handles all the cases.

What do you guys think about that?
Any further ideas about this?

Last but not least, @andrey-ushakov, thank you for this great package. It helped me quite a lot.

[TM-m30] Text alignment issue

Hello,

I'm having a text alignment problem with my EPSON TM-m30 printer.

With the following code, both lines are left aligned:

final CapabilityProfile profile = await CapabilityProfile.load();
final PrinterNetworkManager printerManager = PrinterNetworkManager();
printerManager.selectPrinter('192.168.1.49', port: 9100);

final Ticket ticket = Ticket(PaperSize.mm80, profile);
ticket.text('Text center', styles: PosStyles(align: PosAlign.center));
ticket.text('Text left', styles: PosStyles(align: PosAlign.left));
ticket.cut();

PosPrintResult result = await printerManager.printTicket(ticket);
print('Print result: ${result.msg}');

Result:
image

Version: esc_pos_printer: ^3.2.4

Text not printing in some pinters

in some printers texts not printing...

only printing image.
here is the printer self test print page.
printer

Showing default code page 255 and encoding UTF8

Printer Name : E-POS
Model : ECO250

Ticket Preview

Is there any way to preview the ticket? in terminal or something before print?

Maintenance for this package

@andrey-ushakov Are you working on this package or not? There are 20+ issues that are open and you are not adding any comments on them. Also As I can the last release for this package was made on Mar 12, 2020. Can you please provide an update on it or add some contributors under this package?

Image Raster bug

you need to add this check because if image is already divisible by 8 you add 8 extra pixels and image is distorted.

if(widthPx % 8 != 0) {
final targetWidth = (widthPx + 8) - (widthPx % 8);
final missingPx = targetWidth - widthPx;
final extra = Uint8List(missingPx);
for (int i = 0; i < heightPx; i++) {
final pos = (i * widthPx + widthPx) + i * missingPx;
oneChannelBytes.insertAll(pos, extra);
}
}

export to image or pdf to test

adding a feature as exporting to image or pdf to be able to test the receipt while development without the need of a physical printer .

Hi guys,How to remove pagenumber

I‘m print my code,but title before always have “0”,I try remove it,but I can't. My english not good,i upload image.Thank you:
Rtco7V.jpg
RtcXc9.jpg

CapabilityProfile.load() fails on ios

flutter: >>> Unsupported operation: Isolate.resolvePackageUri, #0      Isolate.resolvePackageUri (dart:isolate-patch/isolate_patch.dart:340:7)
#1      resolveUri (package:resource/src/resolve.dart:11:20)
#2      Resource.readAsString (package:resource/src/resource.dart:74:21)
#3      CapabilityProfile.load (package:esc_pos_utils/src/capability_profile.dart:26:33)
#4      PrinterBloc._selectPrinter (package:aahi_sell/bloc/printer_bloc.dart:108:50)
#5      _rootRunUnary (dart:async/zone.dart:1198:47)
#6      _CustomZone.runUnary (dart:async/zone.dart:1100:19)
#7      _FutureListener.handleValue (dart:async/future_impl.dart:143:18)
#8      Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:696:45)
#9      Future._propagateToListeners (dart:async/future_impl.dart:725:32)
#10     Future._addListener.<anonymous closure> (dart:async/future_impl.dart:393:9)
#11     _rootRun (dart:async/zone.dart:1190:13)
#12     _CustomZone.run (dart:async/zone.dart:1093:19)
#13     _CustomZone.runGuarded (dart:async/zone.dart:997:7)
#14     _CustomZone.bindCallbackGuarded.<anonymous closure> (dart:async/zone.dart:1037:23)
#15     _microtaskLoop (dart:async/schedule_microtask.dart:41:21)
#16     _startMicrotaskLoop (dart:async/schedule_microtask.dart:50:5)

Slow printing text

Resetting the image after every added text slows printing but changing the styling every time does not.
Removed reset() from here:
void textEncoded(
Uint8List textBytes, {
PosStyles styles = const PosStyles(),
int linesAfter = 0,
}) {
_text(textBytes, styles: styles);
// Ensure at least one line break after the text
emptyLines(linesAfter + 1);
reset();
}

and changed this:
bytes += styles.bold ? cBoldOn.codeUnits : [];
bytes += styles.turn90 ? cTurn90On.codeUnits : [];
bytes += styles.reverse ? cReverseOn.codeUnits : [];
bytes += styles.underline ? cUnderline1dot.codeUnits : [];
bytes += styles.fontType == PosFontType.fontB ? cFontB.codeUnits : [];
// Characters size
if (styles.height.value != PosTextSize.size1.value ||
styles.width.value != PosTextSize.size1.value) {
bytes += Uint8List.fromList(
List.from(cSizeGSn.codeUnits)
..add(PosTextSize.decSize(styles.height, styles.width)),
);
}

to this:
bytes += styles.bold ? cBoldOn.codeUnits : cBoldOff.codeUnits;
bytes += styles.turn90 ? cTurn90On.codeUnits : cTurn90Off.codeUnits;
bytes += styles.reverse ? cReverseOn.codeUnits : cReverseOff.codeUnits;
bytes += styles.underline ? cUnderline1dot.codeUnits : cUnderlineOff.codeUnits;
bytes += styles.fontType == PosFontType.fontB ? cFontB.codeUnits : cFontA.codeUnits;
// Characters size
bytes += Uint8List.fromList(
List.from(cSizeGSn.codeUnits)
..add(PosTextSize.decSize(styles.height, styles.width)),
);

and performance improvements were huge.
Consider testing this and if it works for you too consider changing it.

Text alignment

Texts are always aligned left.
It is not updated through the text styling.

Flutter V2.0

Hi,

The image package is use by firebase, they are using the version 3.x.x
Obviously you are using the previous version 2.x.x, have you planned to migrate your package to image 3.x.x?

Maybe integrate the brand new you NullSafe?

Thanks

No reconoce mi impresora bluethoo

Hola estoy tratando de implementar tu package en mi app, pero no me reconoce la impresora bluethoo estoy utilizando una Zebra MZ 220 actualmente tengo el package "blue_thermal_printer", solo que este no me respeta las posiciones de los textos y quiero ver si el tuyo lo hace pero como te comento no me reconoce la impresora y no se por que. Podrias ayudarme a decirme que tendria que hacer para que me la reconozca te lo agradeceria mucho.

Print Code128. Am I code it wrong?

Am I code It wrong, because code type also printed.
I need to only printed 002518276559
Please help

WhatsApp Image 2021-04-08 at 01 00 36

  /// CODE128
  ///
  /// k >= 2
  /// d: '{A'/'{B'/'{C' => '0'–'9', A–D, a–d, $, +, −, ., /, :
  /// usage:
  /// {A = QRCode type A
  /// {B = QRCode type B
  /// {C = QRCode type C
  /// barcodeData ex.: "{A978020137962".split("");


    final List<dynamic> barcdA = "{A002518276559".split("");
    final List<dynamic> barcdB = "{B002518276559".split("");
    final List<dynamic> barcdC = "{C002518276559".split("");

    ticket += generator.text("code128 A");
    ticket += generator.barcode(Barcode.code128(barcdA));
    ticket += generator.text("code128 B");
    ticket += generator.qrcode(Barcode.code128(barcdB));
    ticket += generator.text("code128 C");
    ticket += generator.qrcode(Barcode.code128(barcdC));

Verify if printer is out of paper

How i can verify if my printer is out of paper?

I tested and i get "Success" PosPrintResult message when the printer is out of paper and after i put new paper it starts printing all my past requests.

I'm using EPSON TM-T20X printer and other stuffs are working fine.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.