Как распечатать PDF с обрезанными жесткими полями принтера вместо shift?

#java #printing #pdfbox #java-print

#java #печать #pdfbox #java-печать

Вопрос:

Я пытаюсь распечатать PDF-файл на специальном типе бумаги, где положение содержимого имеет значение, а сдвиг запрещен.

Я использую java.awt.print.PrinterJob и 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);
        }
    }
 

Исходный PDF-файл выглядит следующим образом:

оригинал-pdf

Но напечатанный файл сдвинут:

распечатанный-pdf-с-pdf-коробкой

Итак, вместо shift я ожидаю, что пунктирная граница не будет напечатана вместо сдвига всего документа.

К сожалению, я не смог распечатать PDF-файл без изменения содержимого..

Ответ №1:

Если PrinterJob содержимое задается с помощью setPrintable метода, то during PrinterJob выполняет некоторые действия внутри и изменяет указанное PageFormat ,…

Рабочее решение №1: используйте setPageable и PDFPageable , которое позволяет печатать с использованием формата страницы документа:

     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();
        }
    }

 

Рабочее решение № 2: используйте setPageable и Book просматривайте страницы. Печать Book выполняется с использованием указанного формата страницы:

     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);
        }
    }
 

Другие решения: это мой собственный ответ на мой собственный вопрос. Ответ основан на нескольких часах работы / расследования, потраченных на эту проблему, и, к счастью, нашел какое-то решение.

Если вы знаете, что происходит ниже, и можете предоставить более подробный ответ, объясняющий, что на самом деле происходит, и как именно PrinterJob все работает, тогда я буду рад и с радостью одобрю ваш более подробный ответ.