9

我如何通过在我已经知道的像素中的特定位置写入来使用 java 和 pdfbox 编辑 pdf 页面?

我试过这个,但它覆盖:

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

谢谢你。

4

3 回答 3

21

您本可以使用 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
);
于 2013-10-18T14:00:03.463 回答
2

我想出了如何做到这一点,而不是使用 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();
}

}
于 2013-07-17T10:29:15.500 回答
2

安妮塔是对的。事实上,它工作得很好。我会补充说这一行

page.getContents().getStream();

可能是无关紧要的,并且 PDPage 在较新的版本中被贬低以支持 PDPageable (主要用于打印),但是代码将用于您的目的而不会花费 iText (毕竟,您最初询问过PDF 框)。

不要忘记包括 Anita 为在创建内容流时创建额外位而提供的修复:

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

您还应该记住,您可能会为放置在要覆盖文本的 pdf 顶部的每个打印部分创建和关闭流。您需要确保关闭流和文档,以便写入缓冲区,否则您将看不到您的更改。

此外,对于那些尝试这样做的人,有几个选项可以从 apache 下载 pdfbox 库。我认为,最容易使用的是(目前)名为pdfbox-app-1.8.10.jar 的那个(我目前甚至在我的 JSF 应用程序中都在使用它)。它已经包含了硬连线到 pdfbox 中的其他库,您还需要下载这些库来做任何有意义的事情。

于 2015-07-30T19:06:42.983 回答