skip to Main Content

I’m facing an issue while trying to print the Euro symbol (€) on my thermal receipt using a Bluetooth thermal printer and the https://pub.dev/documentation/bluetooth_print/latest/ package in Flutter.

What I’m using:
Flutter package: bluetooth_print
Printer type: Thermal Bluetooth printer
Encoding: I’ve tried using ISO-8859-15 (Latin-9) to include the Euro (€) symbol.
The Problem:
Whenever I print a line containing the Euro symbol (€), the printer outputs strange characters (for example, a 1 or a garbled symbol). Below is a sample of my current code:

List<int> encodeToLatin9(String input) {
  const latin9Table = {
    '€': 0xA4, // Euro sign in ISO-8859-15
  };

  List<int> encodedBytes = [];
  for (var char in input.runes) {
    if (char < 128) {
      encodedBytes.add(char);
    } else if (latin9Table.containsKey(String.fromCharCode(char))) {
      encodedBytes.add(latin9Table[String.fromCharCode(char)]!);
    } else {
      encodedBytes.add(0x3F); // Replace with '?' if character not found
    }
  }
  return encodedBytes;
}

List<LineText> list = [];
list.add(LineText(
  type: LineText.TYPE_TEXT,
  content: String.fromCharCodes(encodeToLatin9('Total price: 20.00 €')),
  align: LineText.ALIGN_CENTER,
));

What I’ve Tried So Far:
Using UTF-8 Encoding:
I tried:

utf8.encode('Total price: 20.00 €');

Result: The Euro symbol (€) is still displayed incorrectly.

Using Unicode Escape Code (u20AC):
I tried:

'Total price: 20.00 u20AC';

Result: The output is still incorrect.

Replaced Euro Symbol with Alternative Text:
I replaced € with "EUR", which worked fine, but it’s not ideal.

Tested with Another Thermal Printer:
I tested another printer, but the problem persists.

Here a image:
enter image description here

2

Answers


  1. You can use u{20AC}.
    However in most of edge-cases I use bitmap converter to make each character a bitmap image. and then print that.

    I used for logo as well as to print our local currency-format.

    import 'dart:typed_data';
    import 'dart:ui' as ui;
    import 'package:flutter/material.dart';
    
    class TextToBitmapUtil {
      // Method to generate bitmap bytes from text
      static Future<Uint8List> generateBitmapBytes({
        required String text,
        required double fontSize,
        required int totalColumn,
        required TextAlign align,
      }) async {
        final recorder = ui.PictureRecorder();
        final canvas = Canvas(recorder);
        final paint = TextPainter(
          text: TextSpan(
            text: text,
            style: TextStyle(
              fontSize: fontSize,
              color: Colors.black,
            ),
          ),
          textDirection: TextDirection.ltr,
        );
        paint.layout(maxWidth: totalColumn.toDouble());
        paint.paint(canvas, Offset(0, 0));
        final picture = recorder.endRecording();
        final image =
            await picture.toImage(totalColumn, (paint.height / fontSize).ceil());
    
        // Convert the generated ui.Image to raw byte data (bitmap format)
        return await _imageToBytes(image); // Convert the image to bytes
      }
    
      static Future<Uint8List> _imageToBytes(ui.Image image) async {
        final byteData = await image.toByteData(
          format: ui.ImageByteFormat.png,
        ); // You can choose different formats (e.g., PNG, JPEG)
        return byteData!.buffer.asUint8List(); // Return raw byte data
      }
    }
    

    and when I use this on ui/printing side,
    I just call like,

    final bitmapBytes = await TextToBitmapUtil.generateBitmapBytes(
          text: 'Total price: 20.00 €',
          fontSize: 20.0,
          totalColumn: 20,
          align: TextAlign.center,
        );
    

    PS: It might seems overkill to do this simple task. But in certain edge cases, it’ll work.

    Login or Signup to reply.
  2. To print the Euro symbol (€) on a thermal receipt using the bluetooth_print package in Flutter, follow these steps:

    1. Check Printer’s Supported Encoding

    • Most thermal printers use specific character sets. The Euro symbol (€) is in ISO-8859-15 or Windows-1252, not in ISO-8859-1.
    • Check your printer manual to confirm supported encodings.

    2. Set the Printer’s Encoding

    • Send a command to set the correct character encoding. For example, to use Windows-1252:
      List<int> setCodeTableWindows1252 = [27, 116, 16]; // ESC t 16
      await bluetoothPrint.printBytes(setCodeTableWindows1252);
      

    3. Encode Your Text

    • Map the Euro symbol (€) to the correct encoding value. For Windows-1252, it’s 0x80:

      List<int> encodeToWindows1252(String input) {
        const windows1252Table = {'€': 0x80};
        return input.runes.map((char) {
          if (char < 128) return char; // Basic ASCII
          return windows1252Table[String.fromCharCode(char)] ?? 0x3F; // '?' for unsupported
        }).toList();
      }
      
    • Use the encoded text when printing:

      String content = 'Total price: 20.00 €';
      List<int> encodedContent = encodeToWindows1252(content);
      await bluetoothPrint.printBytes(encodedContent);
      

    4. Test and Adjust

    • If it still doesn’t work, confirm your printer’s encoding setup or try replacing with EUR as a fallback.

    This should help you print the Euro symbol correctly!

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search