Мы используем Апплет для печати с принтера со штрих-кодом. Поскольку более новые версии перестали поддерживать апплеты, мне нужно заменить Апплет другим способом печати. нужна помощь, как поступить.
Для содержимого печати мы используем язык шаблонов 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;
}
}
}