0

I'm trying to print PDF on special type of paper, where content's position matter, and shift is not allowed.

I'm using java.awt.print.PrinterJob and org.apache.pdfbox.printing.PDFPrintable:


    public void printPDF(byte[] pdf) throws IOException, PrinterException {
        MediaSize media = MediaSize.getMediaSizeForName(MediaSizeName.ISO_A4);

        PrintRequestAttributeSet attributes = new HashPrintRequestAttributeSet();
        attributes.add(media.getMediaSizeName());
        attributes.add(new MediaPrintableArea(
                0, 0, media.getSize(1)[0], media.getSize(1)[1],
                1
        ));

        PrinterJob job = PrinterJob.getPrinterJob();

        if (job.printDialog(attributes)) {
            PageFormat pageFormat = (PageFormat) job.getPageFormat(attributes).clone();


            Paper paper = pageFormat.getPaper();
            paper.setImageableArea(0, 0, paper.getWidth(), paper.getHeight());
            pageFormat.setPaper(paper);

            PDDocument document = PDDocument.load(pdf);
            PDFPrintable printable = new PDFPrintable(
                    document,
                    Scaling.ACTUAL_SIZE,
                    false,
                    0,
                    false
            );
            job.setPrintable(printable, pageFormat);
            job.print(attributes);
        }
    }

The original PDF looks like this:

original-pdf

But, the printed one is shifted:

printed-pdf-with-pdf-box

So, instead of shift I expect the dashed border to be not printed instead of shift of the whole document.

Unfortunately, I wasn't able to print the PDF without shifting the content,..

kravemir
  • 10,636
  • 17
  • 64
  • 111

1 Answers1

0

If PrinterJob's content is set using setPrintable method, then during PrinterJob does some machinery inside, and modifies specified PageFormat,...

Working solution #1: use setPageable and PDFPageable, which makes print using page format of the document:

    public void printPDF(byte[] pdf) throws IOException, PrinterException {
        PDDocument document = PDDocument.load(pdf);

        PrinterJob job = PrinterJob.getPrinterJob();
        job.setPageable(new PDFPageable(document));

        if (job.printDialog()) {
            job.print();
        }
    }

Working solution #2: use setPageable and Book pageable. The Book makes print using specified page format:

    public void printPDF(byte[] pdf) throws IOException, PrinterException {
        PDDocument document = PDDocument.load(pdf);

        MediaSize media = MediaSize.getMediaSizeForName(MediaSizeName.ISO_A4);
        PrintRequestAttributeSet attributes = new HashPrintRequestAttributeSet();
        attributes.add(media.getMediaSizeName());

        PrinterJob job = PrinterJob.getPrinterJob();

        if (job.printDialog(attributes)) {
            PageFormat pageFormat = (PageFormat) job.getPageFormat(attributes).clone();

            Paper paper = pageFormat.getPaper();
            paper.setImageableArea(0, 0, paper.getWidth(), paper.getHeight());
            pageFormat.setPaper(paper);

            PDFPrintable printable = new PDFPrintable(document, Scaling.ACTUAL_SIZE, false, 0, false);

            Book book = new Book();
            book.append(printable, pageFormat);
            job.setPageable(book);

            job.print(attributes);
        }
    }

Other solutions: this is my own answer to my own question. Answer is based on few hours of work/investigation spent on this issue, and luckily found some solution.

If you know what's going on below, and can provide more detailed answer, explaining what actually goes on, and how exactly PrinterJob things work, then I'll be glad, and happily approve yours more detailed answer.

kravemir
  • 10,636
  • 17
  • 64
  • 111