How can I print a "java.awt.print.Printable" object silently to a PDF?
Few things to note:
I do not have the data as a pdf file
I'm working on existing code, so I cannot step away from the printable interface
So i can print it just fine with job.printDialog(). But I need to be able to do that silently (without user input). The available PDF printer is "Adobe PDF", I suppose others can be installed if needed.
Here's the basic code:
Printable printout = /*object*/;
Book pageable = new Book();
pageable.append(printout, pageFormat);
DocFlavor flavor = DocFlavor.SERVICE_FORMATTED.PAGEABLE;
PrintRequestAttributeSet patts = new HashPrintRequestAttributeSet();
// Add Filepath?
PrintService[] ps = PrintServiceLookup.lookupPrintServices(flavor, patts);
if (ps.length == 0)
throw new IllegalStateException("No Printer found");
PrinterJob job = PrinterJob.getPrinterJob();
job.setPrintService(ps[0]);
job.setPrintable(printout);
I eventually decided to step away from trying to do it in java and instead used a PDF printer which has the option to print silently to a predetermined path.
DocFlavor flavor = DocFlavor.SERVICE_FORMATTED.PAGEABLE;
PrintRequestAttributeSet patts = new HashPrintRequestAttributeSet();
PrintService[] ps = PrintServiceLookup.lookupPrintServices(flavor, patts);
System.out.println("Available printers: " + Arrays.asList(ps));
PrintService myService = null;
for (PrintService printService : ps) {
if (printService.getName().contains("PDF Writer - bioPDF")) {
myService = printService;
break;
}
}
if (myService == null) {
throw new IllegalStateException("bioPDF Printer not found");
}
PrinterJob job = PrinterJob.getPrinterJob();
job.setJobName(jobName);
job.setPrintService(myService);
job.setPrintable(printout);
job.print();
I am printing a .txt file using DocPrintJob. This works fine.
The file will be printed from a Dot Matrix Printer. Now, the issue which I am facing is -:
As per my requirement, the paper needs to set back automatically to
perforated position after printing one record.
But while printing directly from the application, the paper is not automatically setting back to perforated position.
But while giving print of file manually by opening in notepad, printing happens properly with automatic paper adjustment i.e. the paper sets back to the perforated position for next printing
I tried using line feeds and carriage returns at the end of each page. But it didn't work out.
Is there any way out to set the adjustment of printer through code?
Here is my sample code -:
private static void print(String fileName) throws FileNotFoundException, PrintException {
FileInputStream textStream;
textStream = new FileInputStream(fileName);
DocFlavor flavor = DocFlavor.INPUT_STREAM.AUTOSENSE;
Doc mydoc = new SimpleDoc(textStream, flavor, null);
// Set the printer Name
PrintService service = PrintServiceLookup.lookupDefaultPrintService();
PrintServiceAttributeSet printServiceAttributeSet = new HashPrintServiceAttributeSet();
printServiceAttributeSet.add(new PrinterName(service.getName(), null));
// Set the paper size and orientation
PrintRequestAttributeSet printRequestAttributeSet = new HashPrintRequestAttributeSet();
printRequestAttributeSet.add(new MediaPrintableArea(0, 0, 4, 9, MediaPrintableArea.INCH));
printRequestAttributeSet.add(OrientationRequested.LANDSCAPE);
InputStream is = null;
try {
PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();
pras.add(new Copies(1));
DocPrintJob job = service.createPrintJob();
PrintJobWatcher pjw = new PrintJobWatcher(job);
job.print(mydoc, printRequestAttributeSet);
pjw.waitForDone();
}catch(Exception e){
e.printStackTrace();
}
finally{
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
I have made a program that generates text files (.txt) and then displays them in a textArea. I want to take this one step farther and be able to print the text file. It feels like I have tried everything but always get the same result. The text file always varies in length and is normally more than one page long. Using the code below my text file prints but instead of printing multiple pages it prints each page on one/sixth of the a single sheet in landscape. I just need it to print normally. Vertically on multiple pages. I am running on a Linux environment and it is an Epson printer. Any suggestions or feedback would be greatly appreciated.
public static void tryDoc(){
try{
PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();
pras.add(OrientationRequested.PORTRAIT);
DocFlavor flavor = DocFlavor.INPUT_STREAM.TEXT_PLAIN_UTF_8;
PrintService printService[] = PrintServiceLookup.lookupPrintServices(flavor, pras);
PrintService defaultService = PrintServiceLookup.lookupDefaultPrintService();
PrintService service = ServiceUI.printDialog(null, 200, 200, printService, defaultService, flavor, pras);
if(service != null){
DocPrintJob job = service.createPrintJob();
FileInputStream input = new FileInputStream(FileName);
DocAttributeSet das = new HashDocAttributeSet();
Doc doc = new SimpleDoc(input,flavor,das);
job.print(doc, pras);
}
}
catch(Exception e){
System.out.println("Failed");
}
}
What printed page looks like
Hey everyone ,
I'm facing a real problem here while trying to print a pdf file using java print .
The problem is that when i send the file to the printer using print() method with cute pdf the file is well printed but with a real printer it couldn't be done .
`
try{
File file = new File(toprint);
InputStream is = new BufferedInputStream(new FileInputStream(file));
DocFlavor flavor = DocFlavor.INPUT_STREAM.AUTOSENSE;
DocPrintJob job = p.createPrintJob();//p here is my printservice printer
HashPrintRequestAttributeSet printRequestSet = new HashPrintRequestAttributeSet();
HashDocAttributeSet ds=new HashDocAttributeSet();
Doc doc = new SimpleDoc(is, flavor, null);
job.print(doc, aset);
}
catch(Exception e){
System.out.println("An exception occured while printing the file "+ e);
}
`
I've tried it so many times but it doesn't work.
Any ideas?
I think your printer may not have support for pdf, in this case you will have to render it using a pdf renderer.
Look at http://java.net/projects/pdf-renderer and pageable print page.
If you find it helpful I will provide code samples.
We have a number of systems that produce PDFs that need to be printed. These are stored on a central document store. A message then goes onto a JMS queue that the document needs printing. A service, written in Java , picks these up and then invokes a native command. This is to call Adobe Reader with the /t flag. This causes the document to print without the GUI showing.
However since a power cut this no longer works. In the interim we are having to manually print hundreds of documents. We originally tried using Java printing, but the PDFs came out malformed.
What is a better solution to this?
This code only works if the printer supports PDF. Otherwise you need to use a native printer or a Java library. There is a blog article on this at http://pdf.jpedal.org/java-pdf-blog/bid/25566/Printing-PDF-files-from-Java
Show us the code. I remember printing PDF with no issues using Java Print API. Below is the code, might need some modification, but should run as it is,
InputStream in = new FileInputStream(file);
DocFlavor flavor = DocFlavor.INPUT_STREAM.PDF;
// find the printing service
AttributeSet attributeSet = new HashAttributeSet();
attributeSet.add(new PrinterName("FX", null));
attributeSet.add(new Copies(1));
PrintService[] services = PrintServiceLookup.lookupPrintServices(
DocFlavor.INPUT_STREAM.PDF, attributeSet);
//create document
Doc doc = new SimpleDoc(in, flavor, null);
// create the print job
PrintService service = services[0];
DocPrintJob job = service.createPrintJob();
// monitor print job events
PrintJobWatcher watcher = new PrintJobWatcher(job);
System.out.println("Printing...");
job.print(doc, null);
// wait for the job to be done
watcher.waitForDone();
System.out.println("Job Completed!!");
Note:
Flavor is not needed in 2 places, 1 place should be enough. You find that out.
PrintJobWatcher is a nested class, to add a PrintJobListener.
Ever since Java 1.5, Sun developed a pdf renderer library for handling PDF. Now this one is left to Swing Labs. And not sure whether this one would be added into future java APIs.
http://java.net/projects/pdf-renderer/
It is used to view or print pdf files. to print pdf files, you can call this libray. Here is some part of the code.
File input = new File(docName);
FileInputStream fis = new FileInputStream(input);
FileChannel fc = fis.getChannel();
ByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
PDFFile curFile=null;
PDFPrintPage pages=null;
curFile = new PDFFile(bb); // Create PDF Print Page
pages = new PDFPrintPage(curFile);
PrinterJob pjob = PrinterJob.getPrinterJob();
PrintService[] services = pjob.lookupPrintServices();
for(PrintService ps:services){
String pName = ps.getName();
if(pName.equalsIgnoreCase("PrinterName")){
pjob.setPrintService(ps);
System.out.println(pName);
break;
}
}
pjob.setJobName(docName);
Book book = new Book();
PageFormat pformat = PrinterJob.getPrinterJob().defaultPage();
book.append(pages, pformat, curFile.getNumPages());
pjob.setPageable(book);
// print
PrintRequestAttributeSet aset = new HashPrintRequestAttributeSet();
// Print it
pjob.print(aset);
Try using ICEpdf. Here's an example from documentation page:
Document pdf = new Document();
pdf.setFile(filePath);
// create a new print helper with a specified paper size and print
// quality
PrintHelper printHelper = new PrintHelper(null, pdf.getPageTree(),
0f, MediaSizeName.NA_LEGAL, PrintQuality.DRAFT);
// try and print pages 1 - 10, 1 copy, scale to fit paper.
printHelper.setupPrintService(selectedService, 0, 0, 1, true);
// print the document
printHelper.print();
You can use Apache PDFBox. Examples:
a) Printing PDF as Pageable
PrintService printService = PrintServiceLookup.lookupDefaultPrintService();
DocPrintJob printJob = printService.createPrintJob();
PDDocument pdDocument = PDDocument.load(new File("doc.pdf"));
PDFPageable pdfPageable = new PDFPageable(pdDocument);
SimpleDoc doc = new SimpleDoc(pdfPageable, DocFlavor.SERVICE_FORMATTED.PAGEABLE, null);
printJob.print(doc, null);
b) Printing PDF as Printable
This option has advantage that you can control page dimensions, margins, etc. by modifying pageFormat variable.
PrintService printService = PrintServiceLookup.lookupDefaultPrintService();
DocPrintJob printJob = printService.createPrintJob();
PageFormat pageFormat = PrinterJob.getPrinterJob().defaultPage();
PDDocument pdDocument = PDDocument.load(new File("doc.pdf"));
PDFPrintable pdfPrintable = new PDFPrintable(pdDocument);
Book book = new Book();
book.append(pdfPrintable, pageFormat);
SimpleDoc doc = new SimpleDoc(book, DocFlavor.SERVICE_FORMATTED.PAGEABLE, null);
printJob.print(doc, null);