在android热敏打印机中打印阿拉伯字符

问题描述 投票:0回答:4

打印机为GoojPRT便携式打印机PT-210(热敏打印机)

相同的代码在另一台热敏打印机 POS 上有效,但在这台打印机上不适用于阿拉伯字符。英文字符很好,但阿拉伯字符显示为中文字符

尝试添加编码为字符集“UTF-8”并且不适用于阿拉伯字符 打印代码:

Button btnPrint=(Button)findViewById(R.id.btnPrint);
        btnPrint.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                Thread t = new Thread() {
                    public void run() {
                        try {
                            OutputStream os = mBluetoothSocket
                                    .getOutputStream();
                            BILL = "ENGLISH" + "\n";
                            BILL =  BILL + "العربية" + "\n";
                            BILL = BILL + "---------------" + "\n";
                            
                            os.write(BILL.getBytes( ));
                        } catch (Exception e) {

                        }
                    }
                };
                t.start();
            }
        });

扫描打印机:

Button btnScan = (Button) findViewById(R.id.btnScan);
        btnScan.setOnClickListener(new View.OnClickListener() {
            public void onClick(View mView) {
                mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
                if (mBluetoothAdapter == null) {
                    Toast.makeText(ActivityTest.this, "Error", Toast.LENGTH_SHORT).show();
                } else {
                    if (!mBluetoothAdapter.isEnabled()) {
                        Intent enableBtIntent = new Intent(
                                BluetoothAdapter.ACTION_REQUEST_ENABLE);
                        startActivityForResult(enableBtIntent,
                                REQUEST_ENABLE_BT);
                    } else {
                        ListPairedDevices();
                        Intent connectIntent = new Intent(ActivityTest.this,
                                DeviceListActivity.class);
                        startActivityForResult(connectIntent,
                                REQUEST_CONNECT_DEVICE);
                    }
                }
            }
        });

打印样本

我需要打印文本而不是位图或图像

android printing arabic thermal-printer
4个回答
2
投票

我也遇到了同样的问题,经过两天的搜索,我发现,打印阿拉伯语等多语言文本的简单方法是将其绘制在画布上并将其打印为普通图像,如下所示:

    public Bitmap getMultiLangTextAsImage(String text, Paint.Align align, float textSize, Typeface typeface)  {


    Paint paint = new Paint();

    paint.setAntiAlias(true);
    paint.setColor(Color.BLACK);
    paint.setTextSize(textSize);
    if (typeface != null) paint.setTypeface(typeface);

    // A real printlabel width (pixel)
    float xWidth = 385;

    // A height per text line (pixel)
    float xHeight = textSize + 5;

    // it can be changed if the align's value is CENTER or RIGHT
    float xPos = 0f;

    // If the original string data's length is over the width of print label,
    // or '\n' character included,
    // it will be increased per line gerneating.
    float yPos = 27f;

    // If the original string data's length is over the width of print label,
    // or '\n' character included,
    // each lines splitted from the original string are added in this list
    // 'PrintData' class has 3 members, x, y, and splitted string data.
    List<PrintData> printDataList = new ArrayList<PrintData>();

    // if '\n' character included in the original string
    String[] tmpSplitList = text.split("\\n");
    for (int i = 0; i <= tmpSplitList.length - 1; i++) {
        String tmpString = tmpSplitList[i];

        // calculate a width in each split string item.
        float widthOfString = paint.measureText(tmpString);

        // If the each split string item's length is over the width of print label,
        if (widthOfString > xWidth) {
            String lastString = tmpString;
            while (!lastString.isEmpty()) {

                String tmpSubString = "";

                // retrieve repeatedly until each split string item's length is
                // under the width of print label
                while (widthOfString > xWidth) {
                    if (tmpSubString.isEmpty())
                        tmpSubString = lastString.substring(0, lastString.length() - 1);
                    else
                        tmpSubString = tmpSubString.substring(0, tmpSubString.length() - 1);

                    widthOfString = paint.measureText(tmpSubString);
                }

                // this each split string item is finally done.
                if (tmpSubString.isEmpty()) {
                    // this last string to print is need to adjust align
                    if (align == Paint.Align.CENTER) {
                        if (widthOfString < xWidth) {
                            xPos = ((xWidth - widthOfString) / 2);
                        }
                    } else if (align == Paint.Align.RIGHT) {
                        if (widthOfString < xWidth) {
                            xPos = xWidth - widthOfString;
                        }
                    }
                    printDataList.add(new PrintData(xPos, yPos, lastString));
                    lastString = "";
                } else {
                    // When this logic is reached out here, it means,
                    // it's not necessary to calculate the x position
                    // 'cause this string line's width is almost the same
                    // with the width of print label
                    printDataList.add(new PrintData(0f, yPos, tmpSubString));

                    // It means line is needed to increase
                    yPos += 27;
                    xHeight += 30;

                    lastString = lastString.replaceFirst(tmpSubString, "");
                    widthOfString = paint.measureText(lastString);
                }
            }
        } else {
            // This split string item's length is
            // under the width of print label already at first.
            if (align == Paint.Align.CENTER) {
                if (widthOfString < xWidth) {
                    xPos = ((xWidth - widthOfString) / 2);
                }
            } else if (align == Paint.Align.RIGHT) {
                if (widthOfString < xWidth) {
                    xPos = xWidth - widthOfString;
                }
            }
            printDataList.add(new PrintData(xPos, yPos, tmpString));
        }

        if (i != tmpSplitList.length - 1) {
            // It means the line is needed to increase
            yPos += 27;
            xHeight += 30;
        }
    }

    // If you want to print the text bold
    //paint.setTypeface(Typeface.create(null as String?, Typeface.BOLD))

    // create bitmap by calculated width and height as upper.
    Bitmap bm = Bitmap.createBitmap((int) xWidth, (int) xHeight, Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bm);
    canvas.drawColor(Color.WHITE);

    for (PrintData tmpItem : printDataList)
        canvas.drawText(tmpItem.text, tmpItem.xPos, tmpItem.yPos, paint);


    return bm;
}

static class PrintData {
    float xPos;
    float yPos;
    String text;

    public PrintData(float xPos, float yPos, String text) {
        this.xPos = xPos;
        this.yPos = yPos;
        this.text = text;
    }

    public float getxPos() {
        return xPos;
    }

    public void setxPos(float xPos) {
        this.xPos = xPos;
    }

    public float getyPos() {
        return yPos;
    }

    public void setyPos(float yPos) {
        this.yPos = yPos;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }
}

如果您想了解更多详情,请查看这个


0
投票

首先您需要将文本转换为位图图像,然后将图像分割为块并将其发送到打印机,如下所示:

1- 使用这个有用的库进行打印: https://github.com/DantSu/ESCPOS-ThermalPrinter-Android

2- 下面的函数用于分割图像:

private static  void splitImage(Bitmap bitmap,SplitBitmapImage spliter)  {
    Bitmap bmpScale = Bitmap.createScaledBitmap(bitmap, bitmap.getWidth(), bitmap.getHeight(), false);
    int rows = bmpScale.getHeight() /  70 + 1;
    int cols = 1;
    try {
        int chunkHeight = bitmap.getHeight() / rows + 1;
        int chunkWidth = bitmap.getWidth() / cols;
        Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmap, bitmap.getWidth(), bitmap.getHeight(), false);
        int yCoord = 0;
        int var8 = 0;

        for(int var9 = rows; var8 < var9; ++var8) {
            int xCoord = 0;
            int var11 = 0;

            for(int var12 = cols; var11 < var12; ++var11) {
                Bitmap bmp = Bitmap.createBitmap(scaledBitmap, xCoord, yCoord, chunkWidth, chunkHeight);

                if (bmp != null && spliter != null) {
                    Thread.sleep(20);
                    spliter.bitmpaSpliter(bmp);
                }

                xCoord += chunkWidth;
            }

            yCoord += chunkHeight;
        }
    } catch (Exception var14) {
        var14.printStackTrace();
    }

}

3-打印功能

新线程(() -> {

        try {
            EscPosPrinter printer = new EscPosPrinter(MyBluetoothPrintersConnections.selectFirstPairedOne(), 203, 48f, 32);
            Bitmap newbit2 = BitmapUtils.toGrayscale(bytes);
            StringBuilder textToPrint = new StringBuilder();
            splitImage(newbit2, text->{

                    textToPrint.append("[C]<img>" + PrinterTextParserImg.bitmapToHexadecimalString(printer, text) + "</img>\n"+
                            "[L]\n");
            });

            printer.printFormattedTextAndCut(textToPrint.toString());


        } catch (EscPosConnectionException e) {
            e.printStackTrace();
        } catch (EscPosEncodingException e) {
            e.printStackTrace();
        } catch (EscPosBarcodeException e) {
            e.printStackTrace();
        } catch (EscPosParserException e) {
            e.printStackTrace();
        }

}).start();


0
投票

我也遇到过类似的问题,打印东欧字符,但是有一个适用于 Windows 的应用程序可以让您设置默认代码页。首先,您必须安装USB连接打印机的驱动程序,要下载的应用程序在此页面上,您必须翻译它 https://www.facebook.com/groups/284248835817963/posts/432105661032279/ 希望对你有帮助


-1
投票

尝试为阿拉伯文本添加 ISO-8859-6 编码。

© www.soinside.com 2019 - 2024. All rights reserved.