通过"PrintNormal"打印大于124字节的二维码"GS ( k <Function 180>"?

Print QR code "GS ( k <Function 180>" with more than 124 bytes via "PrintNormal"?

我有一台 Epson TM-T88VI 打印机,使用 C# 中的 Microsoft.PointOfService.PosPrinter 进行打印。

我尝试通过 ESC POS 命令打印二维码。

一切正常,直到打印出 125+ 字节的二维码数据。

这是我的功能:

    private string fct180(string data)
    {
        byte[] barr = System.Text.ASCIIEncoding.ASCII.GetBytes(data);
        int len = barr.Length + 3;
        byte pH = (byte)(len / 256);
        byte pL = (byte)(len - (256 * pH));
        byte[] cmd = new byte[8 + barr.Length];
        cmd[0] = 29;
        cmd[1] = 40;
        cmd[2] = 107;
        cmd[3] = pL;
        cmd[4] = pH;
        cmd[5] = 49;
        cmd[6] = 80;
        cmd[7] = 48;
        Array.Copy(barr, 0, cmd, 8, barr.Length);
        string testing = System.Text.ASCIIEncoding.ASCII.GetString(cmd);
        byte[] rere = System.Text.ASCIIEncoding.ASCII.GetBytes(testing);
        string ret = System.Text.ASCIIEncoding.ASCII.GetString(cmd);

        return ret;
    }

我的情况:

1) 首先我尝试生成内容字符串长度为124的二维码: data"AASDFASDFASDFADSFADSFASDFADSFADSFADSFADSFADSFADSFADSFADSFADSFKLJADSJKLFADSJKLFADSJKLFDJKLFDSJKLFADSJLFDSJLKFDJLSKFDJKLSFADXX"

此二维码打印正确(pL为127,pH为0),pL编码为"\u007f":
"\u001d(k\u007fP0AASDFASDFASDFADSFADSFASDFADSFADSFADSFADSFADSFADSFADSFADSFADSFKLJADSJKLFADSJKLFADSJKLFDJKLFDSJKLFADSJLFDSJLKFDJLSKFDJKLSFADXX" rere[3]: 的值 127,rere[4] 的值 = 0

2) 然后我尝试生成一个字符串长度为125的二维码: data"AASDFASDFASDFADSFADSFASDFADSFADSFADSFADSFADSFADSFADSFADSFADSFKLJADSJKLFADSJKLFADSJKLFDJKLFDSJKLFADSJLFDSJLKFDJLSKFDJKLSFADXXT"

此二维码未打印(pL为128,pH为0),pL编码为“?”其字节值为 63:

"\u001d(k?P0AASDFASDFASDFADSFADSFASDFADSFADSFADSFADSFADSFADSFADSFADSFADSFKLJADSJKLFADSJKLFADSJKLFDJKLFDSJKLFADSJLFDSJLKFDJLSKFDJKLSFADXXT"

rere[3]: 的值 63,rere[4] 的值 = 0

我想依次获取两个二维码,但我只获取了一个和第二个二维码的部分内容为纯字符串文本。正如你在这里看到的: 图为1)的二维码和2)的文字部分

前 63 个字符被擦除,字符 64+ 打印为普通文本。 好的,那是因为字节值是63而不是128。但是为什么二维码不是打印63个字符?

这是因为字节值 128 被编码为字符串字符“?”。 但是,如果我不能保留字节值大于 127 的字符串,我如何使用 Microsoft.PointOfService.PosPrinter.PrintNormal 打印我的 QR 码?

PosPrinter class 中是否有接受纯字节数组的替代函数调用?我还没找到。

除了PosPrinter.PrintBarcode还有其他解决办法吗?

你有什么建议?

编辑:解决方案 我使用了字节数组,然后将每个字节(通过 char)转换为字符串。 该字符串使用纯字节值而不是编码。然后我使用转义序列"ESC|[*]#E"。然后在 PrintNormal 中使用它。这会将字符串直接定向到打印机,而无需在两者之间进行处理。现在也可以处理大于 127 的字节值。

        string ESC = System.Text.ASCIIEncoding.ASCII.GetString(new byte[] { 27 });
        byte[] bqr = ...;
        string data = "";
        for (int i = 0; i < bqr.Length; ++i)
        {
            data += (char)bqr[i];
        }
        string cmd = ESC + "|*" + data.Length + "E" + data;
        printer.PrintNormal(PrinterStation.Receipt, cmd)

这涉及到很多复杂的问题。


首先,我回答过上一个问题,如果你使用的是POSfor.NET(包括OPOS/JavaPOS),不要直接用PrintNormal 方法。

如果要打印二维码,PrintBarcode方法可能支持,请查看EPSON的ADK文档,如果在ADK文档中找不到,请联系EPSON支持台。

可以根据 UnifiedPOS 规范为打印机发送 ESC/POS 控制命令。
名为 "Path through embedded data" (ESC|[*]#E) 的 UnifiedPOS POSPrinter 转义序列会将 # 中指定的数据字节直接发送到打印机。
但是,假定服务对象支持该功能。请查看您的 ADK 文档或支持联系人以了解支持可用性。


接下来,这取决于您是使用 POS for.NET 本机服务对象还是通过 COM Interop 使用 OPOS 服务对象。

使用 OPOS 服务对象时,从 Unicode 到 ANSI 代码页的转换由 OLE 运行时函数在方法调用期间自动完成,大于 127 的字符代码可以通过系统代码页更改。此外,如果数据中间有一个 0x00,它将在那里终止,其余数据将被忽略。

这是因为PrintNormal方法的参数是字符串,不是字节数组。

服务对象的

ILegacyControlObject.BinaryConversion property可以改为Nibble或Decimal,而不是默认值None。
但是,根据 POS for.NET 的 COM Interop 的实现,可能需要注意,因此最好联系支持台了解如何使用它。

如果您在 POS for.NET 中使用本机服务对象,则取决于它的实现方式。同样,请查看您的 ADK 文档或联系支持台以获取更多信息。

我遇到了同样的问题,但用不同的方式解决了它

问题在于使用字符串,我们使用 SerialPort.Write() 将数据发送到打印机。

https://docs.microsoft.com/en-us/dotnet/api/system.io.ports.serialport.write?view=dotnet-plat-ext-6.0

它有这个有趣的条款

默认情况下,SerialPort 使用 ASCIIEncoding 对字符进行编码。 ASCIIEncoding 将所有大于 127 的字符编码为 (char)63 或 '?'。要支持该范围内的其他字符,请将编码设置为 UTF8Encoding、UTF32Encoding 或 UnicodeEncoding。

所以我们:

  • 已将所有数据恢复为字节。

    将 SerialPort 设置为 UTF-8 编码。

    并直接发送字节。

我们现在可以打印高达 7000 位的二维码