Friday 5 August 2011

How to print a PDF Document in Java ?

For some time now I have searched for a way to print a PDF document from Java code. Up to now, I have had to shell out and invoke Acrobat from the command line but this hack has been painful to support in the field because of the multiple version of Acrobat and its quirks.
A new PDF Renderer project has recently been released on java.net which can in addition to rendering and viewing a PDF document, it can be used to print a PDF document. If you download the PDF Renderer you can run the jar to start a sample PDF viewer application which can print PDF documents. All the code listed below is inspired from the PDF Renderer sample application.

Use the following two classes :

 PDFPrinter.java

import com.sun.pdfview.PDFFile;
import java.awt.print.Book;
import java.awt.print.PageFormat;
import java.awt.print.PrinterJob;
import java.io.File;
import java.io.FileInputStream;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

/**
 *
 * @author Prasobh.K
 */
public class PDFPrinter {
    private String pdfFile= null;
    public PDFPrinter(String pdfFile){
        this.pdfFile = pdfFile;
    }
    public boolean doPrint(){
       boolean printSucessfull = true;
        try {
            File f = new File(pdfFile);
            FileInputStream fis = new FileInputStream(f);
            FileChannel fc = fis.getChannel();
            ByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
            PDFFile pdfFile = new PDFFile(bb); // Create PDF Print Page
            PDFPrintPage pages = new PDFPrintPage(pdfFile);

           // Create Print Job
            PrinterJob pjob = PrinterJob.getPrinterJob();
            PageFormat pf = PrinterJob.getPrinterJob().defaultPage();
            pjob.setJobName(f.getName());
            Book book = new Book();
            book.append(pages, pf, pdfFile.getNumPages());
            pjob.setPageable(book);

           // Send print job to default printer
            pjob.print();
        } catch (Exception e) {
            printSucessfull = false;
            System.out.println(e);
        }
       return printSucessfull;
    }
  
}

PDFPrintPage .java

import com.sun.pdfview.PDFFile;
import com.sun.pdfview.PDFPage;
import com.sun.pdfview.PDFRenderer;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;


/**
 *
 * @author Prasobh.K
 */
class PDFPrintPage implements Printable {
  private PDFFile file;
  PDFPrintPage(PDFFile file) {
    this.file = file;
  }

  public int print(Graphics g, PageFormat format, int index)
    throws PrinterException {
    int pagenum = index + 1;

    // don't bother if the page number is out of range.
    if ((pagenum >= 1) && (pagenum <= (file.getNumPages()))) {
      // fit the PDFPage into the printing area
      Graphics2D g2 = (Graphics2D)g;
      PDFPage page = file.getPage(pagenum);
      double pwidth = format.getImageableWidth();
      double pheight = format.getImageableHeight();

      double aspect = page.getAspectRatio();
      double paperaspect = pwidth / pheight;

      Rectangle imgbounds;

      if (aspect>paperaspect) {
        // paper is too tall / pdfpage is too wide
        int height= (int)(pwidth / aspect);
        imgbounds= new Rectangle(
          (int)format.getImageableX(),
          (int)(format.getImageableY() + ((pheight - height) / 2)),
          (int)pwidth,
          height
        );
      } else {
        // paper is too wide / pdfpage is too tall
        int width = (int)(pheight * aspect);
        imgbounds = new Rectangle(
          (int)(format.getImageableX() + ((pwidth - width) / 2)),
          (int)format.getImageableY(),
          width,
          (int)pheight
        );
      }

      // render the page
      PDFRenderer pgs = new PDFRenderer(page, g2, imgbounds, null, null);
      try {
        page.waitForFinish();
        pgs.run();
      } catch (InterruptedException ie) {}

      return PAGE_EXISTS;
    } else {
      return NO_SUCH_PAGE;
    }
  }
}


Jar file Used

PDFRenderer-0.9.0.jar
 















 

No comments:

Post a Comment