Hot questions for Using PDFBox in printing


I'm trying to print an existing pdf file with pdfbox. Currently I'm using pdfbox 2.0.0 RC3 through maven.

This is my current code:

PDDocument document = PDDocument.load(new File(myPdfFile));
PrinterJob job = PrinterJob.getPrinterJob();

if (job.printDialog()) {
    job.setPageable(new PDFPageable(document));


For testing I printed a test pdf with Adobe Acrobat and the same pdf with the few lines of code. Everything works fine except for the borders. All borders (header, footer, left & right side) are to small and the footer is way too small.

Is there a magic method that I couldn't find in the world wide web for setting the right scaling/format?


Try this for pdfbox 2.0.0-RC3 version

PDDocument doc = PDDocument.load(new File("test.pdf"));
PDFPrintable printable = new PDFPrintable(doc, Scaling.SHRINK_TO_FIT);
PrinterJob job = PrinterJob.getPrinterJob();

Here is another version

PDDocument doc = PDDocument.load(new File("test.pdf"));
PrinterJob job = PrinterJob.getPrinterJob();

// define custom paper
Paper paper = new Paper();
paper.setSize(306, 396); // 1/72 inch
paper.setImageableArea(0, 0, paper.getWidth(), paper.getHeight()); // no margins

// custom page format
PageFormat pageFormat = new PageFormat();

// override the page format
Book book = new Book();
// append all pages
book.append(new PDFPrintable(doc, Scaling.SHRINK_TO_FIT), pageFormat, doc.getNumberOfPages());



I have 5 printers in Windows 8.1 and the PDF file is not in local system its generated in PHP server.

Question. how can i get the PDF file from the server and print to a specific printer?

I am trying with Apache PDFBox 2.0.0


import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import javax.print.DocPrintJob;
import javax.print.PrintService;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.printing.PDFPageable;

public class JPrint {

  public static boolean saveFile(URL url, String file) throws IOException {
    boolean download_status = false;

    System.out.println("[OK] - open");
    InputStream in = url.openStream();
    FileOutputStream fos = new FileOutputStream(new File(file));
    System.out.println("[OK] - reading file...");
    int length = -1;
    byte[] buffer = new byte[1024];

    while ((length = > -1) {
        fos.write(buffer, 0, length);

    download_status = true;
    System.out.println("[OK] - downloaded");
    return download_status;

  public static void main(String[] args) throws IOException, PrinterException {    
    String downloaded_filename = "C:/Users/tpt/Downloads/pdf.pdf";
    String download_pdf_from = "";
    String downloaded_filename_open_as_pdf = "C:\\Users\\tpt\\Downloads\\pdf.pdf";
    String printerNameDesired = "DYMO LabelWriter 450"; // Brother HL-6180DW series

    // Get printers
    PrintService[] services = PrinterJob.lookupPrintServices();
    DocPrintJob docPrintJob = null;

      URL url = new URL(download_pdf_from);

      if(saveFile(url, downloaded_filename)) {
        try {
          PDDocument pdf = PDDocument.load(new File(downloaded_filename_open_as_pdf));
          PrinterJob job = PrinterJob.getPrinterJob();
          for (int i = 0; i < services.length; i++) {
           if (services[i].getName().equalsIgnoreCase(printerNameDesired)) {
             docPrintJob = services[i].createPrintJob();

          job.setPageable(new PDFPageable(pdf));
          //docPrintJob = service[i].createPrintJob();

        } catch (Exception e) {
          System.out.println("[FAIL]" + e);
      } else {
        System.out.println("[FAIL] - download fail");
    } catch (Exception ae) {
      System.out.println("[FAIL]" + ae);



This gives you back a list of available printers:

PrintService[] services = PrinterJob.lookupPrintServices();

You can loop through this array and select the printer by name (services[i].getName())


I'm using the following set-up:

  • Java 11.0.1

  • pdfbox 2.0.15

Objective: Rendering a pdf that contains Chinese characters

Problem: java.lang.IllegalArgumentException: U+674E is not available in this font's encoding: WinAnsiEncoding

I already tried:

  • Using different fonts for Chinese character support. The latest one is NotoSansCJKtc-Regular.ttf

  • Set font to unicode as described here: Java: Write national characters to PDF using PDFBox, however the used loadTTF method is deprecated.

  • Using Arial-Unicode-MS_4302.ttf

My code looks like this (shortened a bit):

try (InputStream pdfIn = inputStream; PDDocument pdfDocument =
             PDDocument.load(pdfIn)) {

      PDFont formFont;
      //Check if Chinese characters are present
      if (!Util.containsHanScript(queryString)) {
        formFont = PDType0Font.load(pdfDocument,
      } else {
        formFont = PDType0Font.load(pdfDocument,

        List<PDField> fields = acroForm.getFields();

        //Load fields into Map
        Map<String, PDField> pdfFields = new HashMap<>();
        for (PDField field : fields) {
          String key = field.getPartialName();
          pdfFields.put(key, field);

        PDField currentField = pdfFields.get("someFieldID");
        PDVariableText pdfield = (PDVariableText) currentField;

        PDResources res = acroForm.getDefaultResources();
        String fontName = res.add(formFont).getName();
        String defaultAppearanceString = "/" + fontName + " 10 Tf 0 g";


      acroForm.flatten(fields, true);

      ByteArrayOutputStream pdfOut = new ByteArrayOutputStream();;

Expected result: Chinese characters on pdf.

Actual result: java.lang.IllegalArgumentException: U+674E is not available in this font's encoding: WinAnsiEncoding

So my question is about how to best support rendering of Chinese characters with pdfbox. Any help is appreciated.


The following code works for me, it uses the file of PDFBOX-4629:

PDDocument doc = PDDocument.load(new URL("").openStream());
PDAcroForm acroForm = doc.getDocumentCatalog().getAcroForm();
PDVariableText field = (PDVariableText) acroForm.getField("search_query");
List<PDField> fields = acroForm.getFields();
PDFont font = PDType0Font.load(doc, new FileInputStream("c:/windows/fonts/arialuni.ttf"), false);

PDResources res = acroForm.getDefaultResources();
String fontName = res.add(font).getName();
String defaultAppearanceString = "/" + fontName + " 10 Tf 0 g";


acroForm.flatten(fields, true);"saved.pdf");


I'm trying to use PDFBox to print an existing PDF file. Here's the code:

public void sendToPrinter(){
    File PDFFile = new File("Example.pdf");

    try {
        PDDocument pd = PDDocument.load(PDFFile);
    } catch (IOException | PrinterException ex) {
        System.out.println("Error: Couldn't find pdf or printers");

When I run it, however, the program freezes at pd.print(). No exceptions are thrown, no print dialog appears. It just doesn't do anything. Has anyone had this problem before?

Specs: Mac OS X Yosemite, PDFBox v1.8.9, JDK1.8.0_05, HP Photosmart printer


For anyone having the same problem. My print() command worked when I put all the PDF work onto another thread. For reference:

public void sendToPrinter() {

        //Create new Task
        Task task = new Task<Boolean>() {
            public Boolean call() {

                //Reference the PDF file
                File PDFFile = new File("File.pdf");

                try {
                    //Load PDF & create a Printer Job
                    PDDocument pd = PDDocument.load(PDFFile);
                    PrinterJob job = PrinterJob.getPrinterJob();
                    job.setPageable(new PDFPageable(pd));

                    //Show native print dialog & wait for user to hit "print"
                    if (job.printDialog()) {

                } catch (IOException | PrinterException ex) {

                return true;
        //Run task on new thread
        new Thread(task).start();



I'm trying to print a file that I think is landscape mode (it measures 29,7 x 27 cm) but my program stops working when I submit the job.print(). Here's my code:

PDDocument documentAllegato = PDDocument.load(new File(percorsoDaStampare +"\\"+ fileInDaStampare[k].getName()));

job.setPageable(new PDFPageable(documentAllegato));
Attribute[] attributeArray2 = attributes.toArray();
for (Attribute a : attributeArray2) {
    //System.out.println(a.getName() + ": " + a);
Attribute copies2 = attributes.get(Copies.class);
Attribute media2 = attributes.get(Media.class);
Attribute mediaPrintableArea2 = attributes.get(MediaPrintableArea.class);
Attribute mediaTray2 = attributes.get(MediaTray.class);
Attribute orientationRequested2 = attributes.get(OrientationRequested.class);
Attribute sides2 = attributes.get(Sides.class);
//System.out.println("PRIMA DEL PRINT");


documentAllegato.close();   //chiudo il documento
//System.out.println("Ho finito di stampare la copia cortesia");
//sposto la copia di cortesia in ARCHIVIATI
File dirArchiviati = new File(pathArchiviati);
File fileCortesiaDaArch= new File(""+fileInDaStampare[k]);
FileUtils.copyFileToDirectory(fileCortesiaDaArch, dirArchiviati);
//System.out.println("fileDaArch "+ fileCortesiaDaArch);
System.out.println("FINE ALLEGATO");

I tried to put it in portrait mode modifying some stuff but I couldn't get it. Any advice?


I waited over an hour for it to print... this is a known problem, discussed in PDFBOX-3046 and also here and here and here and here: files with transparencies or with patterns take a long time to print. But yours breaks the record. The workaround is to pass a dpi value to PDFPageable which orders it to first render to an image and then print:

job.setPageable(new PDFPageable(documentAllegato, Orientation.AUTO, false, 300));

300 is the dpi value. The bigger this value, the bigger your spool files will be and the more memory will be used.


I have been experimenting with bumping my applications dependency on PDFBox to the 2.0.0 snapshot. I'm having some major issues with it though...

So my code recieves a PDF as a BASE64 String, i decode it, and load the resulting bytearray into a PDDocument. Before I bumped the version number, calling .silentPrint();on the PDDocument worked like a charm.

The implementation of silent printing changed in 2.0.0, and I now do it this way:

private Status doPdfPrint(Document document, PrintService printService) {
    ByteArrayInputStream bais = null;
    PDDocument doc = null;
    PrinterJob printerJob = PrinterJob.getPrinterJob();

    try {
        bais = new ByteArrayInputStream(document.getDecodedData());

        doc = PDDocument.load(bais, true); //Force load

        PDFPrinter pdfPrinter = new PDFPrinter(doc);

    } catch (IOException | PrinterException e) {
        log.warn("Failed to print! Exception occurred: {}", e.getMessage());
        log.debug("EXCEPTION", e);
        return Status.PRINTING_FAILED;
    } finally {
    return Status.PRINTING_OK;

However, when running this on OSX Yosemite, this results in:

2015-02-12 08:10:44.475 java[20264:1353636] Cocoa AWT: Not running on AppKit thread 0 when expected. (
0   libosxapp.dylib                     0x0000000125997782 +[ThreadUtilities getJNIEnv] + 38
1   libawt_lwawt.dylib                  0x000000012bf3004d syncFromJavaPixels + 1842
2   libawt_lwawt.dylib                  0x000000012bf304e3 LockImage + 75
3   libawt_lwawt.dylib                  0x000000012bf43040 Java_sun_java2d_CRenderer_doImage + 170
4   ???                                 0x0000000108c15694 0x0 + 4441855636
5   ???                                 0x0000000108c0798d 0x0 + 4441799053
2015-02-12 08:10:44.475 java[20264:1353636]     Please file a bug     report at with this message and a reproducible test case.
2015-02-12 08:10:44.478 java[20264:1353636] java.lang.StackOverflowError
at sun.java2d.CRenderer.doImage(Native Method)
at sun.java2d.OSXSurfaceData.blitImage(
at sun.java2d.CRenderer.blitImage(
at sun.java2d.CRenderer.scaleImage(
at sun.java2d.CRenderer.transformImage(
at sun.java2d.CRenderer.transformImage(
at sun.java2d.SunGraphics2D.drawImage(
at sun.print.ProxyGraphics2D.drawImage(
at  org.apache.pdfbox.rendering.PageDrawer.drawBufferedImage(
at org.apache.pdfbox.rendering.PageDrawer.drawImage(
at org.apache.pdfbox.contentstream.PDFStreamEngine.processOperator(
at org.apache.pdfbox.contentstream.PDFStreamEngine.processStreamOperators(
at org.apache.pdfbox.contentstream.PDFStreamEngine.processStream(
at org.apache.pdfbox.contentstream.PDFStreamEngine.processPage(
at org.apache.pdfbox.rendering.PageDrawer.drawPage(
at org.apache.pdfbox.rendering.PDFRenderer.renderPage(
at org.apache.pdfbox.rendering.PDFRenderer.renderPageToGraphics(
at org.apache.pdfbox.printing.PDFPrinter$PDFPrintable.print(
at sun.lwawt.macosx.CPrinterJob$
at sun.lwawt.macosx.CPrinterJob.printToPathGraphics(
at sun.lwawt.macosx.CPrinterJob.printLoop(Native Method)
at sun.lwawt.macosx.CPrinterJob.print(
at sun.print.RasterPrinterJob.print(
at org.apache.pdfbox.printing.PDFPrinter.print(
at org.apache.pdfbox.printing.PDFPrinter.silentPrint(
at com.memnon.printr.PrintHandler.doPdfPrint(
at com.memnon.printr.PrintHandler.print(
at com.memnon.printr.PrintHandler.print(
at com.memnon.printr.PrintHandler.print(
at com.memnon.printr.communication.DocumentResponseHandler.handleSuccessful(
at com.memnon.printr.communication.DocumentResponseHandler.handle(
at com.memnon.printr.messaging.PrintConsumer.executePrinterJob(
2015-02-12 08:10:44.493 java[20264:1353636] NSAlert is being used from a background thread, which is not safe.  This is probably going to crash sometimes. Break on void _NSAlertWarnUnsafeBackgroundThreadUsage() to debug.  This will be logged only once.  This may break in the future.
2015-02-12 08:10:46.639 java[20264:1353636] Apple AWT Internal Exception: Printing failed because PMSessionEndDocumentNoDialog() returned -30871.
2015-02-12 08:10:46.639 java[20264:1353636] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Printing failed because PMSessionEndDocumentNoDialog() returned -30871.'
*** First throw call stack:
0   CoreFoundation                      0x00007fff8895c66c __exceptionPreprocess + 172
1   libobjc.A.dylib                     0x00007fff890e876e objc_exception_throw + 43
2   CoreFoundation                      0x00007fff8895c51d +[NSException raise:format:] + 205
3   AppKit                              0x00007fff8d117e80 -[NSPrintSpoolingGraphicsContext dealloc] + 43
4   libobjc.A.dylib                     0x00007fff890fb89c _ZN11objc_object17sidetable_releaseEb + 236
5   libobjc.A.dylib                     0x00007fff890e1e8f _ZN12_GLOBAL__N_119AutoreleasePoolPage3popEPv + 575
6   CoreFoundation                      0x00007fff88834302 _CFAutoreleasePoolPop + 50
7   libawt_lwawt.dylib                  0x000000012bf25fa4 Java_sun_lwawt_macosx_CPrinterJob_printLoop + 165
8   ???                                 0x0000000108c15694 0x0 + 4441855636
9   ???                                 0x0000000108c07160 0x0 + 4441796960
10  ???                                 0x0000000108c0798d 0x0 + 4441799053
libc++abi.dylib: terminating with uncaught exception of type NSException

Any idea what's going on? Regards


So I'm posting here 2 years after this occured for the first time..

It's still occuring. However, it's a Java bug, rather then a PDFBox bug. So after filing my bugreport on PDFBox issue-tracker, I got the advice to set a DPI for the document when doing printing. And voila it works. However, it's nearly impossible to figure out the DPI of a pdf document.

However, if you know what the DPI is, you can simply do this:

final int rasterizedDpi = 203;
final PDDocument pdfDocument = PDDocument.load(data);
final PrinterJob job = PrinterJob.getPrinterJob();
final PDFPageable pageable = new PDFPageable(pdfDocument, Orientation.AUTO, false, rasterizedDpi);

The hint here is the 4th argument to PDFPageable, the dpi...

Until Oracle fixes this JDK bug, i guess we're going to have to call this method :)