Java 在蓝牙打印机上打印 UTF-8 字符

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18231314/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 23:34:12  来源:igfitidea点击:

Printing UTF-8 characters on bluetooth printer

javaandroidbluetoothzebra-printers

提问by Morten

I have an application where I should be able to print on a bluetooth printer, Zebra iMZ320, but I have some problems with UTF-8 specific characters (?, ? or ?).

我有一个应用程序,我应该能够在蓝牙打印机 Zebra iMZ320 上进行打印,但是我在使用 UTF-8 特定字符(?、? 或 ?)时遇到了一些问题。

I am connecting to the device as follows:

我按如下方式连接到设备:

        BluetoothDevice device = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(macAddr);
        Method m = device.getClass().getMethod("createRfcommSocket", new Class[] { Integer.TYPE });
        bSocket = (BluetoothSocket)m.invoke(device, new Object[] { Integer.valueOf(1) });
        bSocket.connect();
        outStream = bSocket.getOutputStream();
        inStream = bSocket.getInputStream();

After the socket is open, I am sending the data in CPCL:

套接字打开后,我在CPCL中发送数据:

        String cpclData = "! U1 SETLP 5 2 24 \r\n"+text+"\r\n";
        outStream.write(cpclData.getBytes());
        outStream.flush();

But when I am trying to print the mentioned characters, it writes some abnormal characters instead.

但是当我尝试打印提到的字符时,它会写一些异常字符。

I contacted Zebra, and one of their engineers wrote that I should try the following:

我联系了 Zebra,他们的一位工程师写道,我应该尝试以下操作:

! 0 200 200 80 1 
IN-MILLIMETERS 
JOURNAL 
CENTER 
COUNTRY NORWAY
TEXT 4 0 0 8 COUNTRY IS NORWAY OR DENMARK
TEXT 4 0 0 15 ? ? ?
PRINT

But it does absolutely nothing.

但它绝对没有任何作用。

采纳答案by Ovi Tisler

Unicode isn't supported in the CPCL language. You can do it in ZPL though, and the iMZ supports ZPL. Check out this link.

CPCL 语言不支持 Unicode。不过,您可以在 ZPL 中执行此操作,并且 iMZ 支持 ZPL。查看此链接

回答by JWqvist

Found this solution here

在这里找到了这个解决方案

public byte[] convertExtendedAscii(String input)
{
        int length = input.length();
    byte[] retVal = newbyte[length];

    for(int i=0; i<length; i++)
    {
              char c = input.charAt(i);

              if (c < 127)
              {
                      retVal[i] = (byte)c;
              }
              else
              {
                      retVal[i] = (byte)(c - 256);
              }
    }

    return retVal;
}

回答by código

it is simple if you try to print a label from android device; when you write the data use "ISO-8859-1" encoding, look:

如果您尝试从 android 设备打印标签,这很简单;当您使用“ISO-8859-1”编码编写数据时,请查看:

String cpclData = "! U1 SETLP 5 2 24 \r\n"+text+"\r\n";
outStream.write(EncodingUtils.getBytes(cpclData, "ISO-8859-1"));
outStream.flush();

回答by jsanmarb

In a similar problem, trying to print spanish special characters on a Zebra MZ220 printer via Bluetooth, finally I did the following (in this answer I add the characters ?, ?, ?, ?, ?, ?) :

在一个类似的问题中,尝试通过蓝牙在 Zebra MZ220 打印机上打印西班牙语特殊字符,最后我做了以下操作(在这个答案中,我添加了字符 ?, ?, ?, ?, ?, ?):

  1. Define a piece of code that converts the objective string into the desired byte array:

    public class Util
    {
        public final static String  caracteresEspeciales        = "üüááééííóóúú????????";
    
        public final static byte[]  codigoCaracteresEspeciales  = new byte[] {(byte) 0xDC, (byte) 0xFC, (byte) 0xC1, (byte) 0xE1, (byte) 0xC9, (byte) 0xE9,
                (byte) 0xCD, (byte) 0xED, (byte) 0xD3, (byte) 0xF3, (byte) 0xDA, (byte) 0xFA, (byte) 0xD1, (byte) 0xF1, (byte) 0xC5, (byte) 0xC6, (byte) 0xD8,
                (byte) 0xE5, (byte) 0xE6, (byte) 0xF8           };
    
        public static byte[] stringABytes(String s)
        {
            int i, l, i_especial;
            byte b;
            byte[] b_arr;
            String s_sub;
    
            if(s == null)
                return null;
            if((l= s.length()) < 1)
                return new byte[0];
    
            // convertimos a byte carácter por carácter
            b_arr= new byte[l];
            for(i= 0; i < l; i++)
            {
                s_sub= s.substring(i, i + 1);
                i_especial= Util.caracteresEspeciales.indexOf(s_sub);
                if(i_especial < 0)
                    b= (s_sub.getBytes())[0];
                else
                    b= Util.codigoCaracteresEspeciales[i_especial];
                b_arr[i]= b;
            }
    
            return b_arr;
        }
    }
    
  1. 定义一段代码,将目标字符串转换为所需的字节数组:

    public class Util
    {
        public final static String  caracteresEspeciales        = "üüááééííóóúú????????";
    
        public final static byte[]  codigoCaracteresEspeciales  = new byte[] {(byte) 0xDC, (byte) 0xFC, (byte) 0xC1, (byte) 0xE1, (byte) 0xC9, (byte) 0xE9,
                (byte) 0xCD, (byte) 0xED, (byte) 0xD3, (byte) 0xF3, (byte) 0xDA, (byte) 0xFA, (byte) 0xD1, (byte) 0xF1, (byte) 0xC5, (byte) 0xC6, (byte) 0xD8,
                (byte) 0xE5, (byte) 0xE6, (byte) 0xF8           };
    
        public static byte[] stringABytes(String s)
        {
            int i, l, i_especial;
            byte b;
            byte[] b_arr;
            String s_sub;
    
            if(s == null)
                return null;
            if((l= s.length()) < 1)
                return new byte[0];
    
            // convertimos a byte carácter por carácter
            b_arr= new byte[l];
            for(i= 0; i < l; i++)
            {
                s_sub= s.substring(i, i + 1);
                i_especial= Util.caracteresEspeciales.indexOf(s_sub);
                if(i_especial < 0)
                    b= (s_sub.getBytes())[0];
                else
                    b= Util.codigoCaracteresEspeciales[i_especial];
                b_arr[i]= b;
            }
    
            return b_arr;
        }
    }
    

Those hexadecimal codes we can get them from PROMAN-CPCL document that coming whith the printer (APPENDIX C- CHARACTER TABLES, Latin 1 Character Set table).

我们可以从打印机随附的 PROMAN-CPCL 文档(附录 C-字符表,Latin 1 字符集表)中获取这些十六进制代码。

  1. Convert the string and send it.

            String datos_cplc;
            byte[] b_arr;
            ...
            datos_cplc= "! 0 200 200 48 1\r\n" + 
                    "TEXT 7 0 0 0 12345678901234567890123456789012\r\n" + 
                    "TEXT 7 0 0 25 üüááééííóóúú???????? AEIOUaeiou1\r\n" + 
                    "FORM\r\n" + 
                    "PRINT\r\n";
            b_arr= Util.stringABytes(datos_cplc);
            ...
            connection.write(b_arr);
    
  2. The result:

  1. 转换字符串并发送。

            String datos_cplc;
            byte[] b_arr;
            ...
            datos_cplc= "! 0 200 200 48 1\r\n" + 
                    "TEXT 7 0 0 0 12345678901234567890123456789012\r\n" + 
                    "TEXT 7 0 0 25 üüááééííóóúú???????? AEIOUaeiou1\r\n" + 
                    "FORM\r\n" + 
                    "PRINT\r\n";
            b_arr= Util.stringABytes(datos_cplc);
            ...
            connection.write(b_arr);
    
  2. 结果:

enter image description here

在此处输入图片说明

回答by Isaac Meany

In my case, it worked perfectly the solution provided by @jsanmarb but using the Code page 850 (Latin-1 - Western European languages) found here: https://www.ascii-codes.com/cp850.html

就我而言,它完美地适用于@jsanmarb 提供的解决方案,但使用此处找到的代码页 850(Latin-1 - 西欧语言):https://www.ascii-codes.com/cp850.html