This problem can be solved in several ways, it all depends on how you need to print.
If the system that you are developing is in delphi, the situation becomes much easier, there are components that make the job much easier, such as ACBR: link
However, the system I'm developing, quoted in the question above, was a JAVA EE application running on a local server, on the machine where the printer was connected.
My first attempt was to generate a PDF file, and to send this file to print on the printer that was connected, however, these argox printer models that I was using NOT accept pdf files. However, I realized that if I just generated the PDF and printed via S.O, the printer was able to print.
But the requirement of the project was to print automatically, without user interaction. The situation above was enough to understand that the Operating System could solve the printing situation.
But if I can not send a PDF, how will I define the layout?
These printers usually have their own language to define the layout of the applications, in the case of this Argox model, it was the PPLB language, just look for the documentation to learn how to create the layouts. >
Code to Print
The code below, does the following steps:
Detects S.O
Injects a command into the terminal to perform printing
The tag.txt file is a file that was previously generated in the PPLB language, with the values to be printed on the label, it is saved at the root of the project, you can create your own tag.txt with only one "hello world "and run the command on the terminal of your OS to test the printout.
public class Etiqueta {
//Imprime a etiqueta de acordo com o sistema operacional
public static void imprimirEtiqueta() throws IOException {
if (SystemUtils.IS_OS_WINDOWS) {
try {
String[] command = {"cmd",};
Process p = Runtime.getRuntime().exec(command);
new Thread(new ThreadSyncPipe(p.getErrorStream(), System.err)).start();
new Thread(new ThreadSyncPipe(p.getInputStream(), System.out)).start();
PrintWriter stdin = new PrintWriter(p.getOutputStream());
stdin.println("type etiqueta.txt > ImpressoraCompartilhadaNoWindows"); //No windows, você precisa compartilhar a impressora na rede e passar o nome dela no comando para imprimir
stdin.close();
int returnCode = p.waitFor();
} catch (Exception e) {
throw new ErrorPrintingLabelException("Erro ao imprimir: Etiqueta ou impressora não encontrada. Erro: "
+ e.getMessage());
}
} else if (SystemUtils.IS_OS_LINUX){
String[] args = new String[] {"/bin/bash", "-c", "cat etiqueta.txt > /dev/usb/lp1"}; //no linux é mais simples, apenas passe o local da impressora
Process proc = new ProcessBuilder(args).start();
} else {
System.out.println("O recurso de impressão de etiquetas não é compatível com este S.O");
}
}
Thread for printing:
import java.io.InputStream;
import java.io.OutputStream;
class ThreadSyncPipe implements Runnable {
public ThreadSyncPipe(InputStream istrm, OutputStream ostrm) {
istrm_ = istrm;
ostrm_ = ostrm;
}
public void run() {
try {
final byte[] buffer = new byte[1024];
for (int length = 0; (length = istrm_.read(buffer)) != -1; ){
ostrm_.write(buffer, 0, length);
}
}
catch (Exception e) {
e.printStackTrace();
}
}
private final OutputStream ostrm_;
private final InputStream istrm_;
}
Although it is a great workaround, it works great in production, I had no problems with printing.