srehanuddin / Cordova-Plugin-Bluetooth-Printer

A cordova plugin for bluetooth printer for android platform
103 stars 115 forks source link

[Support] Printing non english characters like '¡' #22

Open luchillo17 opened 7 years ago

luchillo17 commented 7 years ago

I'm printing in spanish and this character ¡, is not used in english, so how would i make it happen? it shows a weird subindexed Tand a weird í instead.

I was taking a look at http://stackoverflow.com/questions/5396560/how-do-i-convert-special-utf-8-chars-to-their-iso-8859-1-equivalent-using-javasc thinking it's an encoding issue.

srehanuddin commented 7 years ago

For this i made canvas image on html5, then print base64 string via printImage method

luchillo17 commented 7 years ago

I get the idea, someone was doing the same in stack overflow with arabic language characters, however the implementation has me lost, i'll have to look at it later, more important things first.

luchillo17 commented 7 years ago

I've seen the ESC t command and it makes me think i can use it to change to an spanish code table, however i've tried almost all of them and this spanish accent haven't been able to make it work: ó.

Isn't there any simpler way instead of just playing with base64 images about those special chars?

It's a big workaround that would have to be implemented too general in my case, since most of the time idk what will be printed, most of it comes from database.

Ping @srehanuddin.

philpm commented 7 years ago

@Luchillo @srehanuddin I think there may add a method to set charsetName for print string. I want print Chinese charset,so i edit the java file "/src/android/BluetoothPrinter.java" on line:261 like this: mmOutputStream.write(msg.getBytes("GBK"));

So,if you want print multi lang ,I think you can create a method like this false code: `boolean setLang(CallbackContext callbackContext, String lang) throws IOException { try {

        this.lang=lang; 
        return true;

    } catch (Exception e) {
        String errMsg = e.getMessage(); 
        callbackContext.error(errMsg);
    }
    return false;
}`

and modify the print method like this: mmOutputStream.write(msg.getBytes(this.lang));

then modify the js"www/BluetoothPrinter.js", add code like this:

setLang: function(fnSuccess, fnError, str){ exec(fnSuccess, fnError, "BluetoothPrinter", "setLang", [str]); },

before you do print you may do setLang first.

CesarBalzer commented 7 years ago

Luchilo and philpm this command that is using "GBK" is for Chinese characters, I need to use accentuation, but I have not found the command of latin languages for this, does anyone know the list of language commands or any reference?

philpm commented 7 years ago

@CesarBalzer try ISO-8859-1

CesarBalzer commented 7 years ago

@philpm It did not work on the printer I'm testing, I had tried with UTF-8, it did not work, and ISO-8859-1 also did not work, it follows a photo of the printed paper with the characters for better understanding.

I tried again by canceling the Chinese characters with the command: mmOutputStream.write(0x1C); mmOutputStream.write(0x2E);

This String: César áâàäâ íîˆïuü

captura de tela 2017-01-14 as 13 14 44

philpm commented 7 years ago

these code may help you where i copy from my native android project.

try { String e = new String(bytes); int couts = 0; int j; if(this.language != 0) { if(1 == this.language) { ArrayList var8 = this.str16(e);

                for(j = 0; j < var8.size(); ++j) {
                    int var9 = ((Integer)var8.get(j)).intValue();
                    if(10 == var9) {
                        this.PrinterController_Linefeed();
                    } else {
                        this.mOutputStream.write(var9);
                    }
                }

                return 0;
            } else {
                if(2 == this.language) {
                    this.mOutputStream.write(bytes);
                }

                return -1;
            }
        } else {
            String[] strs16 = new String[e.length()];

            for(j = 0; j < e.length(); ++j) {
                strs16[j] = e.substring(j, j + 1);
            }

            for(j = 0; j < strs16.length; ++j) {
                if("\n".equals(strs16[j])) {
                    this.PrinterController_Linefeed();
                } else {
                    ++couts;
                    byte[] a = new byte[]{strs16[j].getBytes("unicode")[3], strs16[j].getBytes("unicode")[2]};
                    this.mOutputStream.write(a);
                }
            }

            return 0;
        }
    } catch (Exception var7) {
        var7.printStackTrace();
        return -1;
    }
luchillo17 commented 7 years ago

Is there another solution? i've opted for removing all diacritics but now some other characters have issues, for example - gets outputted as [Çô, any help on this?

CesarBalzer commented 7 years ago

@luchillo17 I'm still working but unsuccessfully for accented character printing, no one has yet managed a solution apparently. I tried to use the @philpm code snippet but it also did not work.

raeziel commented 7 years ago

I have managed to print accented characters with the inclusion of the following lines into the printText function on BluetoothPrinter.java:

mmOutputStream.write(0x1C); mmOutputStream.write(0x2E); // Cancels Chinese  character mode (FS .)
mmOutputStream.write(0x1B); mmOutputStream.write(0x74); mmOutputStream.write(0x10); // Select character code table (ESC t n) - n = 16(0x10) for WPC1252
mmOutputStream.write(msg.getBytes("iso-8859-1")); 

I used this as source: http://content.epson.de/fileadmin/content/files/RSD/downloads/escpos.pdf

CesarBalzer commented 7 years ago

This is wonderful @raeziel , I just do the tests, finally is printing correctly the accented characters, thank you for the collaboration, now a pull request for the @srehanuddin analyze and publish in the master version, we are waiting 2 requests for pull request, who knows soon he publishes. String of test: ÁÉÍÓÚãõêçáéíóúãõêç∆∆∆César

ybwrlpwsdqfqatogel7p_eq9svke2jejzny0g9qpej13wvxibtfhxoksm_2j0v4kojgpqph95zl2okpyzg6usbjlqh3pztjs2zwv_wdevyl-dvr3ra6zmlninpbg9bds677g2je4pvlj2vhyiztfjdqzauwypbtm7hibcka1rpuxk1r3pjhrtvhmfkwiu9g6ckrc2y3axxatidab1hgulbhm29m8xmvz

raeziel commented 7 years ago

You can send the same configuration to the printer for changing the codepage with the string "\x1C\x2E\x1B\x74\x10" via BTPrinter.printText so there's no need to mess with the JAVA file.

luchillo17 commented 7 years ago

@raeziel Does such config get erased when the ESC @ => '1B 40' command is sent to the printer?

raeziel commented 7 years ago

@luchillo17 ESC @ command resets the printer to the original state just like turning it off so you need to send the configuration string every time. I included the string at the beginning of my print function so I don't need to worry if its on or not.

CesarBalzer commented 7 years ago

You are right @raeziel , I forgot that it is not only in PT-BR that it will be used, thank you anyway.

luchillo17 commented 7 years ago

Nice, i'll try this week.

luchillo17 commented 7 years ago

@raeziel How do you send it? i'm having no success doing it like this:

public async printTextWrapper(str: string) {
    await this.printText('\x1C\x2E\x1B\x74\x10');
    this.printText(str);
}

It still missprint the ¿ character as well as diacritics like ó as Ã3, do you send 2 BTPrinter.printText(str), one with \x1C\x2E\x1B\x74\x10 and the second with text?, or you prepend such text to the string to print?.

luchillo17 commented 7 years ago

@raeziel Nop, tried sending the text before the string, then tried prepending the text like

public async printTextWrapper(str: string) {
    this.printText('\x1C\x2E\x1B\x74\x10' + str);
}

But no luck.

raeziel commented 7 years ago

@luchillo17 I forgot to mention I still need the convertion in the JAVA file with 'mmOutputStream.write(msg.getBytes("iso-8859-1"))'. My bad. The \x bytes within the string can be included at any moment. As an example the ESC - n enables underline text. You can turn it on or off at any time inside the string: "\x1B\x2D\x01underline mode on \x1B\x2D\x00underline mode off" I didn't found an easy way to convert the "UTF8" string to "ISO-8859-1" within the JS code. Tested on printer : "\x1C\x2E\x1B\x74\x10á, é, í, ó, ú, ü, ñ, ¿, ¡\n\n\n\n"

img_20170604_204630 1

luchillo17 commented 7 years ago

@raeziel Yes, i figured i was lacking something, i also tried converting the text to iso-8859-1 but no luck.

So the fix has yet to be merge to the repo? or any fork that already accepts this?

lf-tavares commented 6 years ago

@raeziel your code works fine to me. Thanks a lot!

I'm using a PTP Leopardo A7 printer

mmOutputStream.write(0x1C); mmOutputStream.write(0x2E); // Cancels Chinese character mode (FS .) mmOutputStream.write(0x1B); mmOutputStream.write(0x74); mmOutputStream.write(0x10); // Select character code table (ESC t n) - n = 16(0x10) for WPC1252 mmOutputStream.write(msg.getBytes("iso-8859-1"));

siva0205 commented 5 years ago

i am using https://github.com/bakrianto/Cordova-Plugin-BTPrinter plugin. is working perfectly base64 image. some time printer hang. no out put. i change to printer firmware (format the printer) and its working perfect. how to use with out hanging problem. please help sir.

djerick1989 commented 4 years ago

Hi @raeziel your code works fine for á, é, í, ó, ú but i am still have a problem with $ character it is printing like Ұ

           outputStream.write(0x1C);
            outputStream.write(0x2E); // Cancels Chinese  character mode (FS .)
            outputStream.write(0x1B);
            outputStream.write(0x74);
            outputStream.write(0x10); // Select character code table (ESC t n) - n = 16(0x10) for WPC1252
            outputStream.write(msg.getBytes("ISO-8859-1"));
            outputStream.write(PrinterCommands.LF);