I would like to print (on printer) RTF file in JAVA and get result of this operation.
I found 2 possibilities but none of them satisfy my requirements:
package com.shell;
import java.awt.Desktop;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import static java.util.stream.Collectors.toList;
import java.util.stream.IntStream;
import javax.print.Doc;
import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.SimpleDoc;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.Copies;
import javax.print.event.PrintJobEvent;
import javax.print.event.PrintJobListener;
class Printer {
public static void main(String[] args) {
Printer printer = new Printer();
printer.print();
}
void print() {
String template = "C:\\Users\\user\\Documents\\pakiety\\work\\a%d.rtf";
List<File> files = IntStream.rangeClosed(1, 1)
.mapToObj(i -> String.format(template, i))
.map(path -> new File(path))
.collect(toList());
files.forEach(file -> {
printFile2(file);
});
}
void printFile2(File file) {
try {
Desktop.getDesktop().print(file);
} catch (IOException ex) {
Logger.getLogger(Printer.class.getName()).log(Level.SEVERE, null, ex);
}
}
void printFile(File file) {
PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
aset.add(new Copies(1));
PrintService service = PrintServiceLookup.lookupDefaultPrintService();
List<DocFlavor> flavors = Arrays.asList(service.getSupportedDocFlavors());
DocFlavor flavor = flavors.get(13); // I've tried from 0 to 13 (size of list is 14 on my computer)
try (FileInputStream in = new FileInputStream(file)) {
Doc doc = new SimpleDoc(in, flavor, null);
DocPrintJob job = service.createPrintJob();
job.addPrintJobListener(new CustomPrintJobListener(file.getName()));
job.print(doc, aset);
}
catch (Exception ex) {
Logger.getLogger(Printer.class.getName()).log(Level.SEVERE, null, ex);
}
}
private class CustomPrintJobListener implements PrintJobListener {
private final String name;
public CustomPrintJobListener(String name) {
this.name = name;
}
@Override
public void printDataTransferCompleted(PrintJobEvent pje) {
System.out.println("printDataTransferCompleted: " + name);
}
@Override
public void printJobCompleted(PrintJobEvent pje) {
System.out.println("printJobCompleted: " + name);
}
@Override
public void printJobFailed(PrintJobEvent pje) {
System.out.println("printJobFailed: " + name);
}
@Override
public void printJobCanceled(PrintJobEvent pje) {
System.out.println("printJobCanceled: " + name);
}
@Override
public void printJobNoMoreEvents(PrintJobEvent pje) {
System.out.println("printJobNoMoreEvents: " + name);
}
@Override
public void printJobRequiresAttention(PrintJobEvent pje) {
System.out.println("printJobRequiresAttention: " + name);
}
}
}
First solution printFile with PrintService class doesn't work because I don't have supported DocFlavor for RTF file. Also I don't know how could I guarantee that client will have DocFlavor supporting RTF file (using Print Service API).
Second solution printFile2 with Desktop class doesn't allow me to get result of print method.
When I've tried print GIF file and set appropriate DocFlavor.INPUT_STREAM.GIF, then program (method printFile) works fine and print success/fail depending on real print result (I've tested this with Microsoft Print to PDF).
This code:
PrintService service = PrintServiceLookup.lookupDefaultPrintService();
List<DocFlavor> flavors = Arrays.asList(service.getSupportedDocFlavors());
flavors.forEach(f -> System.out.println(f));
gives this result:
image/gif; class="[B"
image/gif; class="java.io.InputStream"
image/gif; class="java.net.URL"
image/jpeg; class="[B"
image/jpeg; class="java.io.InputStream"
image/jpeg; class="java.net.URL"
image/png; class="[B"
image/png; class="java.io.InputStream"
image/png; class="java.net.URL"
application/x-java-jvm-local-objectref; class="java.awt.print.Pageable"
application/x-java-jvm-local-objectref; class="java.awt.print.Printable"
application/octet-stream; class="[B"
application/octet-stream; class="java.net.URL"
application/octet-stream; class="java.io.InputStream"
How can I print RTF file and get result of print operation (fail/success)? I will accept any JAVA solution that satisfy this simple requirement: print file on paper with return value or action with print status (onSuccess/onFail).
I consider converting RTF to PDF file, and then print PDF but I believe that there is better solution.