Printooth字符编码失效,无法打印西里尔文问题求助
解决Printooth库打印西里尔文乱码问题
我使用Printooth库打印西里尔文字符"Тест"时,测试了库中所有预设编码都无法正常显示,但打印机本身支持西里尔文(已通过应用商店的打印应用验证)。以下是问题代码及解决方案:
问题代码
public void testPrint(View view){ ArrayList<Printable> printables = getTestPrint("Тест"); PairedPrinter printer = new PairedPrinter(name, mac); Printooth.INSTANCE.printer(printer).print(printables); } public static ArrayList<Printable> getTestPrint(String text){ ArrayList<Printable> printables = new ArrayList<>(); Byte lineSpacing = (byte) Settings.lineSpacing(context); int spaceAfter = Settings.spaceAfter(context); printables.add(gerRawPrintable()); Map<String, Byte> bytes = Printer.getCharacterCode(); for(var entry: bytes.entrySet()){ printables.add(new TextPrintable.Builder() .setText(entry.getKey() + " - " + text) .setCharacterCode((byte) entry.getValue()) .setCustomConverter(new DefaultConverter()) .setAlignment(DefaultPrinter.Companion.getALIGNMENT_LEFT()) .setNewLinesAfter(spaceAfter) .setLineSpacing(lineSpacing) .build() ); } return printables; } public static RawPrintable gerRawPrintable(){ return new RawPrintable.Builder(new byte[]{27, 100, 4}).build(); } public static Printable getPrintElement(String text, Byte lineSpacing, byte characterCode){ return new TextPrintable.Builder() .setText(text) .setAlignment(DefaultPrinter.Companion.getALIGNMENT_LEFT()) .setNewLinesAfter(Settings.spaceAfter(MainActivity.context)) .setLineSpacing(lineSpacing) .setCharacterCode(characterCode) .build(); } public static Map<String, Byte> getCharacterCode(){ Map<String, Byte> bytes = new HashMap<>(); bytes.put("ARABIC CP720", DefaultPrinter.Companion.getCHARCODE_ARABIC_CP720()); ... bytes.put("WEU", DefaultPrinter.Companion.getCHARCODE_WEU()); return bytes; }
解决方案
1. 自定义西里尔文编码转换器
默认DefaultConverter未适配西里尔文编码,需实现自定义转换器:
public class CyrillicConverter implements Converter { @Override public byte[] convert(String text, CharacterCode characterCode) { try { // 优先测试打印机支持的西里尔文编码,如CP866或CP1251 return text.getBytes("CP866"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); return text.getBytes(); } } }
2. 修改打印机初始化指令
打印前发送切换到西里尔文字符集的ESC指令(不同打印机指令可能不同,需参考手册):
public static RawPrintable getCyrillicInitPrintable(){ // 示例:切换到CP866字符集(指令为ESC + t + 2) return new RawPrintable.Builder(new byte[]{27, 116, 2}).build(); }
3. 调整测试代码
聚焦测试西里尔文相关编码,使用自定义转换器:
public static ArrayList<Printable> getTestPrint(String text){ ArrayList<Printable> printables = new ArrayList<>(); Byte lineSpacing = (byte) Settings.lineSpacing(context); int spaceAfter = Settings.spaceAfter(context); // 使用西里尔文初始化指令 printables.add(getCyrillicInitPrintable()); // 只保留西里尔文相关编码测试 Map<String, Byte> cyrillicCodes = new HashMap<>(); cyrillicCodes.put("CYRILLIC CP866", DefaultPrinter.Companion.getCHARCODE_CYRILLIC_CP866()); cyrillicCodes.put("CYRILLIC CP1251", DefaultPrinter.Companion.getCHARCODE_CYRILLIC_CP1251()); for(var entry: cyrillicCodes.entrySet()){ printables.add(new TextPrintable.Builder() .setText(entry.getKey() + " - " + text) .setCharacterCode(entry.getValue()) .setCustomConverter(new CyrillicConverter()) // 应用自定义转换器 .setAlignment(DefaultPrinter.Companion.getALIGNMENT_LEFT()) .setNewLinesAfter(spaceAfter) .setLineSpacing(lineSpacing) .build() ); } return printables; }
额外注意
- 务必查阅打印机官方手册,确认支持的西里尔文编码及对应的字符集切换指令
- 如果库中无预设西里尔文
characterCode,可尝试仅发送字符集切换指令,不调用setCharacterCode,直接用自定义转换器处理字节转换
内容的提问来源于stack exchange,提问作者Dima Chibuk
相关产品推荐
相关产品推荐

