使用 pdfbox 编辑 pdf 页面
Posted
技术标签:
【中文标题】使用 pdfbox 编辑 pdf 页面【英文标题】:Edit pdf page using pdfbox 【发布时间】:2013-07-15 03:23:01 【问题描述】:我如何通过在我已经知道的像素中的特定位置写入来使用 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();
谢谢。
【问题讨论】:
【参考方案1】:我知道怎么做,而不是使用 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();
【讨论】:
这不是已发布问题的正确答案。【参考方案2】:您本可以使用 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
);
【讨论】:
【参考方案3】:安妮塔是正确的。事实上,它工作得很好。我会添加这一行
page.getContents().getStream();
可能是多余的,并且 PDPage 在较新的版本中被贬低以支持 PDPageable (主要用于打印),但代码将用于您的目的而不会花费 iText 的费用(毕竟,您最初询问PDFBox)。
不要忘记包含 Anita 为在创建内容流时创建额外位而提供的修复:
PDPageContentStream contentStream = new PDPageContentStream(
document, page, true, true);
您还应该记住,您可能会为放置在要覆盖文本的 pdf 顶部的每个打印部分创建和关闭流。您需要确保关闭流和文档,以便写入缓冲区,否则您将看不到您的更改。
另外,对于那些尝试这个的人,有几个选项可以从 apache 下载用于 pdfbox 的库。我认为最容易使用的是(目前)名为 pdfbox-app-1.8.10.jar 的那个(我目前甚至在我的 JSF 应用程序中都在使用它)。它已经包含其他硬连线到 pdfbox 中的库,您还需要下载这些库才能做任何有意义的事情。
【讨论】:
具有三个布尔参数的PDPageContentStream
构造函数是一个更好的选择。它试图确保在新流开始时图形状态处于默认状态。
我同意这一点。不是必需的,但是当您做每件需要做的事情时,很高兴知道图形处于什么状态。 OP通过忽略他写的“with java and pdfbox”部分回答了他自己的问题,这太糟糕了,他给出了一个他随后接受的itext答案。 Anita 给了他一个有效且符合问题的答案。以上是关于使用 pdfbox 编辑 pdf 页面的主要内容,如果未能解决你的问题,请参考以下文章
PDFBOX 2.0.18 - 如何遍历 PDF 页面并检索特定字段