Замена апплета, который принимает печать с принтера штрих-кода - PullRequest
1 голос
/ 03 мая 2020

Мы используем Апплет для печати с принтера со штрих-кодом. Поскольку более новые версии перестали поддерживать апплеты, мне нужно заменить Апплет другим способом печати. нужна помощь, как поступить.

Для содержимого печати мы используем язык шаблонов Free Marker, в Java мы обрабатываем содержимое FTL с токенами и передаем sh вывод в браузер как обычный текст.

Из кода апплета мы генерируем кнопку печати в браузере и выпадающий список принтеров, чтобы принять печать.

Ниже приводится содержимое печати. ​​ ^Q38,3 ^W75 ^H15 ^P1 ^S4 ^AT ^C1 ^R0 ~Q+0 ^O0 ^D0 ^E12 ~R200 ^L Dy2-me-dd Th:m:s BA,63,146,3,7,100,0,0,${sample_no} AC,25,38,1,1,0,0,NAME: AC,130,38,1,1,0,0,[#if patient.visit_type != 'in']${(patient.full_name)!}[#else]${(patient.patient_name)!}[/#if] AC,25,81,1,1,0,0,AGE: AC,126,81,1,1,0,0,${patient.age}/[#if patient.visit_type != 'in']${patient.agein}[#else]Y[/#if] AC,218,81,1,1,0,0,SEX: AC,298,81,1,1,0,0,${patient.patient_gender} AE,168,253,1,1,0,0,${sample_no} E

Код апплета:

public class PrintApplet extends JApplet implements ActionListener {

    private String printText;
    private byte[] printBytes;
    private Properties props;

    private static String PRINTER_KEY1 = "hms_user_printer1";
    private static String PRINTER_KEY2 = "hms_user_printer2";
    private static String TOTAL_PRINTERS_KEY = "total_printers";
    private static String AUTO_CLOSE = "auto_close";

    @Override
    public void init() {
        props = loadProperties();

        JSObject win = JSObject.getWindow(this);
        JSObject doc = (JSObject) win.getMember("document");
        JSObject textarea = (JSObject) doc.call("getElementById",new Object[] { "printData" });
        printText = (String) textarea.getMember("value");
        printText = printText.replace("\n", "\r\n"); // some printers need// \r, others treat \n// as \r\n
        printBytes = unescape(printText.getBytes());

        try {
            java.awt.EventQueue.invokeLater(new Runnable() {
                public void run() {
                    setLookAndFeel();
                    initComponents();
                }
            });
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    /* Method for printer2*/
    public void actionPerformedOnPrinterOne() {

        // get number of printers entered by user
        String numberOfPrinters = props.getProperty(TOTAL_PRINTERS_KEY);

        if (numberOfPrinters == null || numberOfPrinters.equals("")) {
            //  ask user number of  printers
            numberOfPrinters = JOptionPane.showInputDialog(this, "Please enter the number of printers" +
                    " (Note: supported for only two printers, enter in numeric)");

            if (numberOfPrinters == null || numberOfPrinters.equals("")) {
                JOptionPane.showMessageDialog(this, "You did not specify the number of printers. " +
                        "To enter the number of printers please click Print again");
                return;
            }

            numberOfPrinters = numberOfPrinters.trim();
            if (!numberOfPrinters.equals("1") && !numberOfPrinters.equals("2")) {
                JOptionPane.showMessageDialog(this, "Please specify only 1 or 2" +
                        "To enter the number of printers please click Print again");
                return;
            }

            props.setProperty(TOTAL_PRINTERS_KEY, numberOfPrinters);
            saveProperties(props);
        }

        doPrint(PRINTER_KEY1);
    }

    /* Method for printer2*/
    public void actionPerformedOnPrinterTwo() {
        doPrint(PRINTER_KEY2);
    }

    public void doPrint(String printerKey) {

        String printer = props.getProperty(printerKey);

        if (printer == null || printer.equals("")) {
            // ask the user for the printer
            printer = JOptionPane.showInputDialog(this,
                    "Please enter the name of the printer (for eg: LPT1)");

            printer = printer.trim();

            if (printer == null || printer.equals("")) {
                JOptionPane.showMessageDialog(this,
                        "You did not specify the printer, to enter the printer please click on Print again",
                        "Printer name",
                        JOptionPane.INFORMATION_MESSAGE);
                return;
            }

            props.setProperty(printerKey, printer);
            saveProperties(props);
        }

        FileOutputStream os = null;
        try {
            os = new FileOutputStream(printer);
            os.write(printBytes);
            os.flush();
            String autoClose = props.getProperty(AUTO_CLOSE);
            if ((autoClose != null) && autoClose.equals("Y")) {
                JSObject win = JSObject.getWindow(this);
                if (win != null) {
                    System.out.println("Going to close containing window");
                    win.call("close", new Object[] { null });
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
            JOptionPane.showMessageDialog(this, "Failed to print :" + e.getMessage(), "Print Failure",
                    JOptionPane.ERROR_MESSAGE);
        } finally {
            if (os != null) {
                try { os.close(); } catch (Exception e) { /*ignore*/ }
            }
        }
    }

    /* Action performer*/
    public void actionPerformed(ActionEvent ae) {
        if (ae.getActionCommand().equals("Printer-1")) {
            actionPerformedOnPrinterOne();
        } else {
            actionPerformedOnPrinterTwo();
        }
    }

    /* Create buttons*/
    private void initComponents() {

        int numPrinters = 1;
        String numPrintersStr = props.getProperty(TOTAL_PRINTERS_KEY);

        if (numPrintersStr != null && !numPrintersStr.equals(""))
            numPrinters = Integer.parseInt(numPrintersStr);

        for (int i=1; i<=numPrinters; i++) {
            javax.swing.JButton printButton;
            printButton = new javax.swing.JButton();
            printButton.setText("Printer-"+i);
            printButton.addActionListener(this);
            setLayout(new GridLayout());
            add(printButton);
        }
    }

    private void setLookAndFeel() {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (UnsupportedLookAndFeelException e) {
        } catch (ClassNotFoundException e) {
        } catch (InstantiationException e) {
        } catch (IllegalAccessException e) {
        }
    }

    private Properties loadProperties() {
        Properties props = new Properties();
        String homedir = System.getProperty("user.home");
        File prefs = new File(homedir, ".insta.pref");
        if (prefs.exists()) {
            FileInputStream fis = null;
            try {
                fis = new FileInputStream(prefs);
                props.load(fis);
            } catch (Exception e) {
            } //ignored
            finally {
                if (fis != null) {
                    try {
                        fis.close();
                    } catch (IOException e) {
                    } //ignored
                }
            }
        }

        return props;
    }

    private void saveProperties(Properties props) {
        String homedir = System.getProperty("user.home");
        File prefs = new File(homedir, ".insta.pref");
        FileOutputStream fos = null;
        try {
            if (!prefs.exists()) {
                prefs.createNewFile();
            }
            fos = new FileOutputStream(prefs);
            props.store(fos, "");
        } catch (Exception e) {
        } //ignored
        finally {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException e) {
                } //ignored
            }
        }
    }

    public static enum State {NORMAL, AFTER_SLASH, HEX_HIGH, HEX_LOW }; 
    public static byte[] unescape(byte[] bytes) {
        int dest = 0;
        State state = State.NORMAL;
        byte hexHighVal = 0;

        for (int source = 0; source < bytes.length; source++) {
            byte b = bytes[source];
            if (state == State.HEX_HIGH) {
                // just store the high val and continue
                hexHighVal = b;
                state = State.HEX_LOW;

            } else if (state == State.HEX_LOW) {
                // decode the hex character
                int high = getIntVal(hexHighVal);
                int low = getIntVal(b);
                if (high == -1 || low == -1) {
                    // invalid, copy over original, don't decode
                    bytes[dest++] = '\\';
                    bytes[dest++] = 'x';
                    bytes[dest++] = hexHighVal;
                    bytes[dest++] = b;
                } else {
                    byte val = (byte) (high * 16 + low);
                    bytes[dest++] = val;
                } 
                state = State.NORMAL;

            } else if (state == State.AFTER_SLASH) {
                // handle an escaped value
                state = State.NORMAL;
                if (b == '\\')
                    bytes[dest++] = '\\';
                else if (b == 'e')
                    bytes[dest++] = 0x1B;       // escape char
                else if (b == 'f')
                    bytes[dest++] = 0x0C;       // form feed char
                else if (b == 'b')
                    bytes[dest++] = 0x08;       // backspace char
                else if (b == 't')
                    bytes[dest++] = 0x09;       // tab char
                else if (b == '0')
                    bytes[dest++] = 0x0;        // NULL
                else if (b == 'r')
                    bytes[dest++] = '\r';       // carriage return
                else if (b == 'n')
                    bytes[dest++] = '\n';       // line feed
                else if (b == 'x')
                    state = State.HEX_HIGH;
                else {
                    bytes[dest++] = '\\';       // do not decode, retain original
                    bytes[dest++] = b;
                }

            } else if (b == '\\') {
                state = State.AFTER_SLASH;

            } else {
                // normal character
                bytes[dest++] = b;
            }
        }

        // end of loop, if escape sequence is incomplete, output verbatim
        if (state != State.NORMAL) {
            bytes[dest++] = '\\';
            if (state != State.AFTER_SLASH) {
                // hex high or hex low
                bytes[dest++] = 'x';
                if (state == State.HEX_LOW) {
                    bytes[dest++] = hexHighVal;
                }
            }
        }

        // if last 3 chars are \f\r\n, remove \r\n because we want to end with \f
        if (bytes[dest-1] == '\n' && bytes[dest-2] == '\r' && bytes[dest-3] == 0x0C) {
            dest = dest-2;
        }

        return java.util.Arrays.copyOf(bytes, dest);
    }

    public static int getIntVal(byte b) {
        if (b >= 0x30 && b <= 0x39) {
            // 0 - 9
            return b - 0x30;
        } else if (b >= 0x41 && b <=0x46) {
            // A - F
            return b - 0x41 + 10;
        } else if (b >= 0x61 && b <=0x66) {
            // a - f
            return b - 0x61 + 10;
        } else {
            // invalid char
            return -1;
        }
    }
}
...