Reputation: 176
Context:
I have an EOS thermal printer, but it does not print Arabic characters properly like in this image below:
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
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:
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:
I am managing it with styling.
Some useful Flutter SDKs for Thermal Printer which provides Arabic language support:
Upvotes: 1
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
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