I have a requirement to print pdf files in two different ways -one through web page where user will see the print preview and choose the printer and print it. Second way is to automate the printing, just by clicking a button, the pdf should be sent to printer.
The first way of printing is through web page is working fine, but not the second way. The default printer is successfully retrieved for automatic printing, but is not getting printed and I am not getting any error as well. Following are my analysis:
DocFlavor
is not supported. Then I listed
down the supported DocFlavor
of that printer and one of them was
application/octet-stream, which is DocFlavor.INPUT_STREAM.AUTOSENSE
.
So the flavor is supported by printer.PrintJobListener
to check if the print job is
failed. When I added that listener to the printJob, it prints
No_More_Events
and DATA_TRANSFER_COMPLETE
, which should have printed
JOB_COMPLETE
, if the job is success.job.print()
, it goes into Win32PrintJob.print()
method. I did F6 to
execute each line to see what its doing. I compared it with the code
in GrepCode, as the source code was not loaded in eclipse. It
was going fine and I could not see any error. The only place it did
not go into is this block where it checks for the mDestination
value, since I have not provided it, it did not go through. Please see the code below:
if (mDestination != null) { // if destination attribute is set
try {
FileOutputStream fos = new FileOutputStream(mDestination);
byte [] buffer = new byte[1024];
int cread;
while ((cread = instream.read(buffer, 0, buffer.length)) >= 0) {
fos.write(buffer, 0, cread);
}
fos.flush();
fos.close();
} catch (FileNotFoundException fnfe) {
notifyEvent(PrintJobEvent.JOB_FAILED);
throw new PrintException(fnfe.toString());
} catch (IOException ioe) {
notifyEvent(PrintJobEvent.JOB_FAILED);
throw new PrintException(ioe.toString());
}
notifyEvent(PrintJobEvent.DATA_TRANSFER_COMPLETE);
notifyEvent(PrintJobEvent.JOB_COMPLETE);
service.wakeNotifier();
return;
}
This is the only place where it says JOB_COMPLETE. I think this block is to write into a file, which is not needed for me.
I think the actual printing takes place in the following line in the same method Win32PrintJob.print().
private native boolean More ...printRawData(byte[] data, int count);
But this one is native method and so I don't know what is happening inside this.
Please let me know why I am not able to print the PDF.
EDIT:
Attached the code to print the file:
PrintService pss = PrintServiceLookup.lookupDefaultPrintService();
DocPrintJob job = pss.createPrintJob();
DocAttributeSet das = new HashDocAttributeSet();
Doc document;
try {
document = new SimpleDoc(new FileInputStream(new File(fileName)), DocFlavor.INPUT_STREAM.AUTOSENSE, das);
PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();
job.addPrintJobListener(new PrintJobWatcher());
job.print(document, pras);
}
NOTE: I tried different flavors like PDF, PCL. Nothing is working and I get runtime error that it is not supported.
I've recently had the same task and the answer is not so straight forward for the second printing option (also tried JPedal, Samba, and other solutions..). The most simple way to print (which I ultimately tried) was to simply place the file in the printer queue, a.k.a the root location. Ex : MY_SERVER\PRINTER_NAME\
The problem now becomes an environnement/O.S one, and not a Java one. Through an app installed on a Windows machine, you could possibly access that folder, copy the file you want printed, and voila. Furthermore, using the methods you use, you could also give the print job a name, number of copies, etc.
However, once the app is installed on the server, it's a whole different ball game, especially if you are working with Linux servers.
First of all you would have to translate the Windows adresses to Linux ones to even try to copy the file/print it.
Second of all, and this is key, it is very rare/difficult for a printer to just "accept a file" for printing, if it is not part of a more complicated/proprietary Stream of data. For example you could find out the printers "communication language" with the server or even your machine when you do "Ctrl+P"..this will be mostly .xml files or some other format.
But/and in order to "figure" out this format you would have to develop (ultimately in Java) an applet that would call that printer.
You could of course, also try to install Cups4j on that server or have a printer server setup (assuming where you work this isn't in place), but this will cause problems when printers will change, be added to the network, etc.
Ultimately either you would stick to the "Ctrl+P" approach, make a little JS script that calls "CTRL+P" in the browser or start re-creating the wheel, which is not a bad thing (since there are people who choose this approach also..but I haven't found an exemple anywhere), but would take you probably more time than you have.
Hope I helped in some way (sorry for the long post..but it's a subject I've searched and worked on for a good period of time).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With