Редактирование pdf-страницы с помощью pdfbox

Как я могу редактировать pdf-страницу с помощью java и pdfbox, написав в определенной позиции, которую я уже знаю в пикселях ?

Я пробовал это, но он перезаписывает:

PDDocument document = null;
try {
    document = PDDocument.load(new File("/x/x/x/mypdf.pdf"));
    PDPage page = (PDPage) document.getDocumentCatalog().getAllPages().get(0);
    PDFont font = PDType1Font.HELVETICA_BOLD;
    PDPageContentStream contentStream = new PDPageContentStream(document, page);
    page.getContents().getStream();
    contentStream.beginText();
    contentStream.setFont(font, 12);
    contentStream.moveTextPositionByAmount(100, 100);
    contentStream.drawString("Hello");
    contentStream.endText();
    contentStream.close();
    document.save("/x/x/x/mypdf.pdf");
    document.close();
} catch (IOException e) {
    e.printStackTrace();
} catch (COSVisitorException e) {
    e.printStackTrace();
}

спасибо.

3 ответов


вы могли бы использовать PDFBox, все, что вам не хватает, это добавление к странице. Просто измените эту строку:

PDPageContentStream contentStream = new PDPageContentStream(document, page);

в:

PDPageContentStream contentStream = new PDPageContentStream(document, page, true, true);

начиная с PDFBox 2.0,boolean appendContent был заменен AppendMode APPEND такой, что эквивалент предыдущего кода теперь:

PDPageContentStream contentStream = new PDPageContentStream(
    document, page, PDPageContentStream.AppendMode.APPEND, true
);

Я понимаю, как это сделать, вместо использования pdfbox я использовал iTextpdf, это код java, который я использовал:

package ma;

import java.io.*;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.*;

public class editPdf {

public static void main(String[] args) throws IOException,
        DocumentException {

    PdfReader reader = new PdfReader("/Users/Monssef/Desktop/mypdf.pdf");
    PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(
            "/Users/Leonidas/Desktop/mypdfmodified.pdf"));
    BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252,
            BaseFont.NOT_EMBEDDED);

        PdfContentByte over = stamper.getOverContent(1);

        over.beginText();
        over.setFontAndSize(bf, 10);
        over.setTextMatrix(107, 107);
        over.showText("page updated");
        over.endText();

    stamper.close();
}

}

Анита права. На самом деле это работает довольно хорошо. Я бы добавил, что строка

page.getContents().getStream();

возможно, посторонний, и PDPage обесценивается в пользу PDPageable в новых выпусках (и используется в основном для печати), но код будет работать для вашей цели, не переходя на счет iText (и в конце концов, вы изначально спросили о PDFBox).

Не забудьте включить исправление, которое Анита дала для создания дополнительных битов в создании contentstream:

PDPageContentStream contentStream = new PDPageContentStream(
        document, page, true, true);

вы также должны помнить, что вы, вероятно, будете создавать и закрывать потоки для каждого раздела печати, который вы размещаете поверх pdf, на который накладываете текст. Вам нужно будет обязательно закрыть как потоки, так и документ, чтобы буферы были записаны, иначе вы не увидите свои изменения.

кроме того, для тех, кто пытается это сделать, есть несколько вариантов загрузки библиотек из apache для pdfbox. Самый простой используйте, я думаю, (в настоящее время) тот, который называется pdfbox-app-1.8.10.Джар (который я в настоящее время использую даже в своих приложениях JSF). Он уже включает в себя другие библиотеки, которые жестко связаны с pdfbox, которые вам также нужно будет загрузить, чтобы сделать что-нибудь значимое.