ِِAbdallah Al Hallak
ِِAbdallah Al Hallak

Reputation: 176

EOS thermal printer does not print Arabic characters properly when using Flutter framework

Context:

I have an EOS thermal printer, but it does not print Arabic characters properly like in this image below:

Incorrect Arabic encoding

As you can see, the Arabic text is printed incorrectly and from Left-to-Right (LTR), (it should be Right-to-Left - RTL).

Note: You can clearly see the English text is printed perfectly at the end of the page.

Question:

How can I print Arabic text the right way in flutter?

Additional Info:

Flutter version: 2.5.3 (Stable)

Package Used: escpos

Tested on multiple Android devices running Android version (8, 9 ,10)

Upvotes: 9

Views: 4049

Answers (3)

ankushlokhande
ankushlokhande

Reputation: 1854

If you are using the Flutter framework and your EOS thermal printer is not printing Arabic characters correctly, you can try the following solution:

  • Add validations or checks to the style component:

Code: blue_print_pos

receiptText.addText(
 '${invoiceCard.name}',
 alignment: defaultEnLang ? ReceiptAlignment.left : ReceiptAlignment.right,
);

or

Code: esc_pos_utils

bytes += ticket.textEncoded(
 '${invoiceCard.name}',
 styles: PosStyles(
   align: defaultEnLang ? PosAlign.left : PosAlign.right,
   bold: true,
 ),
);

The boolean value of defaultEnLang is retrieved based on the current language.

Expected Output:
Invoice
I am managing it with styling.


Update 2023:

Some useful Flutter SDKs for Thermal Printer which provides Arabic language support:

  • bluetooth_thermal_printer - This is a Flutter plugin that allows you to use a Bluetooth thermal printer on an Android device.
  • blue_print_pos - This is a Flutter plugin that enables you to use a POS (point of sale) system on both Android and iOS devices.
    This is the updated forked blue_print_pos SDK which I used in Dec 2022. You can use it without facing any issues.

Upvotes: 1

B14ck
B14ck

Reputation: 71

you can check this

this repo use 3 laiblary

secreenshot to convert widget to image and image library to convert it to uint8 and pos pront to print it as u love to show

u can check it from here

Upvotes: 2

ِِAbdallah Al Hallak
ِِAbdallah Al Hallak

Reputation: 176

first I have used the esc_pos package and it didn't work. In the end, I've used the printing package to print an Arabic invoice and it works fine, and the explanation below

This is the full code to use the printing package. first, create a class to pass the parameters to it(the parameters that you need to print) in my case 4 required param.

class HtmlGeneratorParamsAccount {
  final String daybet, payable, balance;
  final List<AccountStatmentModel> list;

  HtmlGeneratorParamsAccount({
    required this.daybet,
    required this.payable,
    required this.balance,
    required this.list,
  });
}

String generateHtmlA(HtmlGeneratorParamsAccount p) {
  String items = '''
    ''';

  for (var i = 0; i < p.list.length; i++) {
    DateFormat datee = DateFormat('yyyy/MM/dd', 'en');
    DateTime forFormat = p.list[i].date;
    final String formatted = datee.format(forFormat);
    double amount = p.list[i].debitAmount + p.list[i].payableAmount;
    items += '''<tr class = "item">''';

    items += '''<td>${p.list[i].description}</td>''';
    items += '''<td>${formatted}</td>''';
    items += '''<td>${p.list[i].opName}</td>''';
    items += '''<td>${double.parse(amount.toStringAsFixed(1))}</td>''';
    items += '''</tr>''';
  }
  var pay = double.parse(p.payable).toStringAsFixed(1);
  var day = double.parse(p.daybet).toStringAsFixed(1);
  var html = """ 

then you need to use HTML to build the body of your invoice(shape)

    <!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href=
"https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" />
    <style>

      .invoice-box {
        max-width:1000px;
        margin: auto;
        padding: 8px;
        border: 1px solid #eee;
        box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);
        font-size: 8px;
        line-height: 24px;
        font-family: 'Helvetica Neue', 'Helvetica', Helvetica, Arial, sans-serif;
        color: #555;
      }
        .invoice-box table {
        width: 100%;
        line-height: inherit;
        text-align: center;
      }

      .invoice-box table td {
        padding: 10px;
        vertical-align: top;
      }
 
      .invoice-box table tr.top table td {
        padding-bottom: 5px;
      }

* {
  box-sizing: border-box;
}


.column {
  float: right;
  width:23%;
  
  padding: 16px;
 
}
.header{
text-align:center;
}


.row:after {
  content: "";
  display: table;
  clear: both;
}
 
</style>
</head>
<body>
<h2 class="header">كشف حساب</h2>
<h3 class="header">بيانات الزبون</h3>
<table>
<tr>
<div class="row">
  <div class="column" >
    <h4>المبلغ</h4>
    <p></p>
  </div>
 
  <div class="column" >

    <h4>نوع العملية</h4>
    
  </div>

  <div class="column" >
    <h4>تاريخ</h4>
   
  </div>
  <div class="column" >
    <h4>وصف</h4>
    
  </div>
</div>
</tr>
$items
</table>
<div>
<p class="header">------------------------</p>
<p class="header">:مجموع ${day}</p>
<p class="header">:مجموع $pay</p>
<p class="header">:المبلغ ${p.balance}</p>
<p>---</p>
<p>--</p>
<p>-</p>
</div>
</body>
</html>""";
  return html;

'''

create a function

when you need to use it (in button for example)

printDoc(HtmlGeneratorParamsAccount params) async {

await Printing.layoutPdf(
  onLayout: (format) async => await Printing.convertHtml(
    format: format,
    html: generateHtmlA(params),
  ),
);

} now we will use the printDoc function inside IconButton

the params is the class we've made in the beginning, and we will pass the required parameters

 IconButton(
          onPressed: () {
            HtmlGeneratorParamsAccount params=
                HtmlGeneratorParamsAccount(
              list: list,
              payable: payableAmount.toString(),
              daybet: debitTxt.toString(),
              balance: balance.toString(),
            );
            printDoc(params);
          },
          icon: Icon(
            Icons.print,
          )),

Upvotes: 5

Related Questions