-1

I am making an app that uses fiscal printer, and the document that i send to the printer must be in Cyrillic. The problem is that one specific character (one for the tariff group because i am trying to print out a receipt) should be (char)192, but somehow in the process gets changed to some random character. I've tried changing the encoding of the project to UTF-8 under Project>Properties>Resource>Text file encoding and nothing changed. I've also tried changing the encoding in Window>Preferences>General>Workspace>Text file encoding to UTF-8 and still nothing.

Note: when I type the document manually on other machines and then send it to the fiscal printer it works fine (but not on my pc though). I use notepad to edit the file the output file type is .in.

Here is the code

if(result==JOptionPane.YES_OPTION){
    try {
        PrintWriter writer;
        writer = new PrintWriter("PF500.in");

        String line1 = " 01,0000,1";
        writer.println(line1);
        String etq = "#1";
        String line2 = null;
        String tarifa = null;
        for(Artikli art : list){
            switch(etq){
                case "#1": etq = "$1";
                break;
                default: etq = "#1";
            }
            switch(art.tarifa){
                case "0801": tarifa = Character.toString((char)192);
                break;
                case "0701": tarifa = Character.toString((char)193);
                break;
                case "0601": tarifa = Character.toString((char)194);
                break;
            }
            line2 = etq + art.name.trim() + Character.toString((char)9) + tarifa + art.cena + "*" + art.kolicina;
            writer.println(line2);
        }
        writer.println("%5" + Character.toString((char)9) + "P" + String.valueOf(total));
        writer.println("#" + Character.toString((char)56));

        writer.close();
    } catch (FileNotFoundException e1) {
        e1.printStackTrace();
    }               

    con.clearSmetka(id);
    con.insertIzvestaj(list, den.date, id, user.name, time, popust);
    dtm1.setRowCount(0);
    smetkaTable.setModel(dtm1);
    btnCloseSmetka.setEnabled(false);   
    btn.setBackground(new Color(0, 128, 128));
    btn.setText("Маса " + String.valueOf(id));
    smetkaTxt.setText("0,00");
    workFrame.dispose();
}

Everything works fine except the character for the tariff group (which is (char)192)

Max Vollmer
  • 8,412
  • 9
  • 28
  • 43
Zozinski
  • 73
  • 8
  • The mentioned configurations are only for text editors how to read and write text files. `(char)192` is `À`, right? How do you send the character to the printer? – howlger Aug 30 '18 at 14:13
  • @howgler Yes that's right, it is À. I use a PrintWriter and then "writer.println()" and the line for the character is "tarifa = Character.toString((char)192);" – Zozinski Aug 30 '18 at 14:21
  • @howlger And I also call fiscal32.exe via my app to call the printer itself. That's provided by the manufacturer – Zozinski Aug 30 '18 at 14:29
  • `tarifa = Character.toString((char)192);` can be shorten to `tarifa = "\u00c0";`. `PrintWriter` uses the default character encoding if it is not set in the constructor (if this is the case, use e. g. [this constructor](https://docs.oracle.com/javase/8/docs/api/java/io/PrintWriter.html#PrintWriter-java.io.OutputStream-boolean-) instead). Please add the Java code to your question. It is still unclear how the printer gets the `À`. – howlger Aug 30 '18 at 14:37
  • @howlger I added the code that generates the À. What I also noticed is that sometimes Alt+192 generates this character "└". I am using the instructions from the manufacturer and it says the document should contain ASCII code 192 – Zozinski Aug 30 '18 at 14:56
  • [ASCII](https://en.wikipedia.org/wiki/ASCII) only ranges up to 127. `└` is 192 in [this extended ASCII](https://theasciicode.com.ar/). Does `(char)181` instead of `(char)192` give you `À`? – howlger Aug 30 '18 at 15:43
  • @howlger No, it gives "µ" this character – Zozinski Aug 30 '18 at 17:38

3 Answers3

1

Problem:

In

writer = new PrintWriter("PF500.in");

a PrintWriter is created

which will encode characters using the default charset for this instance of the Java virtual machine.

This means that in

writer.println(line2);

the string line2 that contains the substring "À" (which is the same as "\u00c0" or Character.toString((char)192)) is converted to bytes based on the default charset/encoding (which itself depends on the language setting of the operating system).

Solutions:

  • To directly write the byte 192 without converting it you can use a FileOutputStream instead of the PrintWriter and the method write(int b):
FileOutputStream writer = new FileOutputStream("PF500.in");
...
writer.write('\u00c0');  
  • If you want to continue using the PriterWriter instead, you must specify the encoding/charset that is used by the printer: PrintWriter(File file, String csn).

  • Specify the charset/encoding of the printer when running Java via -Dfile.encoding=... (which could lead to encoding problems elsewhere).

  • As a fourth option, which is not recommended and may work or may not work, you can do an inverse conversion first:

case "0801": tarifa = new String(new byte[]{(byte)192});
howlger
  • 31,050
  • 11
  • 59
  • 99
0
  1. Instead of writing tarifa = Character.toString((char)192);, which is super obfuscating anyways, simply write the character you want directly: tarifa = "À";

  2. When you print a String, it is completely irrelevant how it was constructed and what encoding you used to construct it. Java Strings have an internal character representation that is independent from the encoding you use when creating them or the encoding you use when getting raw data from them. When you create your PrintWriter, you use a constructor that uses the default encoding for your system. That encoding is the crux here. Whatever that encoding is, it obviously is incompatible with your fiscal printer. You should find out what encoding the printer expects, and then construct your PrintWriter with that encoding specifically:

    writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream("PF500.in"), "CHARSET_NAME"));

Max Vollmer
  • 8,412
  • 9
  • 28
  • 43
  • I've tried that, doesn't work. I also print the ascii value of the character that i'am sending to the file and it's correct - 192. But somehow still the fiscal printer isn't recognizing it. The fiscal printer is working properly by the way, I've tested it on other machines – Zozinski Aug 31 '18 at 13:51
0

SOLUTION

Ok, so after some time I finally found the problem: Here I changed PrintWriter with Writer and I set the encoding of the FileOutputStream to "Cp1252" in the following line:

Writer writer = new BufferedWriter(new OutputStreamWriter( new FileOutputStream("PF500.in"), "Cp1252")); Now it works fine. Turns out, for still unknown reasons to me, that the file was saved with utf-8 encoding and the fiscal printer didn't recognize all the characters, hence the faulty receipts. After changing the encoding to "Cp1252", the process works well.

Zozinski
  • 73
  • 8