0

我正在处理一个pdf文件。我需要在现有的 pdf 文件上添加水印。这就是为什么,我写了下面的代码。当我使用 FileOutputStream 时它工作得很好,但我需要使用 ByteArrayOutputStream 因为我的数据来自数据库,我需要将它保存为字节数组。问题从这里开始。当我使用 PdfStamper 的 ByteArrayOutputStream getOvercontent 方法时返回 null。我该如何处理?提前致谢。

byte[] bytes = getAsByteArray();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(bytes.length);
PdfReader reader = new PdfReader(bytes);
int numberOfPages= reader.getNumberOfPages();
outputStream.write(bytes, 0, bytes.length);
PdfStamper stamper = new PdfStamper(reader, outputStream);
Font font = font(Font.NORMAL, 135, Color.RED);
for (int i = 0; i < numberOfPages; i++) {
     //over Content is null
     PdfContentByte over = stamper.getOverContent(i);
     Phrase p = new Phrase("WATERMARK", font);
     PdfGState gs = new PdfGState();
     gs.setFillOpacity(0.5f);
     over.setGState(gs);
     ColumnText.showTextAligned(over, Element.ALIGN_CENTER, p, 330, 450, 45);
     over.saveState();
}

旧版本的代码是这样的。

byte[] bytes = FileUtils.readFileToByteArray(new File("myPdf.pdf"));
PdfReader reader = new PdfReader(bytes);
int numberOfPages= reader.getNumberOfPages();
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("MyPdfOut.pdf"));
Font f = font(Font.NORMAL, 135, Color.RED);
for (int i = 1; i <= numberOfPages; i++) {
    PdfContentByte over = stamper.getOverContent(i);
    Phrase p = new Phrase("WATERMARK", f);
    PdfGState gs = new PdfGState();
    gs.setFillOpacity(0.5f);
    over.setGState(gs);
    ColumnText.showTextAligned(over, Element.ALIGN_CENTER, p, 330, 450, 45);
    over.saveState();
}
4

1 回答 1

2

这是禁止的:

ByteArrayOutputStream outputStream = new ByteArrayOutputStream(bytes.length);
outputStream.write(bytes, 0, bytes.length);
PdfStamper stamper = new PdfStamper(reader, outputStream);

您创建了一个OutputStream名为的outputStream,并且您似乎将一个完整的现有 PDF 复制到该文件中OutputStream(使用write())。然后,您似乎打算OutputStream通过将其传递OutputStreamPdfStamper实例来添加另一个完整的 PDF。这应该会导致 PDF 文件损坏。

这也会导致非法的 PDF 语法

 PdfContentByte over = stamper.getOverContent(i);
 Phrase p = new Phrase("WATERMARK");
 PdfGState gs = new PdfGState();
 gs.setFillOpacity(0.5f);
 over.setGState(gs);
 ColumnText.showTextAligned(over, Element.ALIGN_CENTER, p, 330, 450, 45);
 over.saveState();

你有一个saveState()运算符,但你从不使用restoreState(). 对于每一个saveState(),你应该有一个restoreState(). 你saveState()的位置不对!就好像你不知道什么saveState()restoreState()是关于什么的。

最后,您开始数 0,但第一页是第 1 页,而不是第 0 页。因此for (int i = 0; i < numberOfPages; i++)是错误的。应该是for (int i = 1; i <= numberOfPages; i++)。这个错误是over导致null.

这是尝试修复您的代码:

// create a Phrase with a certain font
Font font = font(Font.NORMAL, 135, Color.RED);
Phrase p = new Phrase("WATERMARK", font);
// Create a reader and a stamper
PdfReader reader = new PdfReader(getAsByteArray());
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
PdfStamper stamper = new PdfStamper(reader, outputStream);
int numberOfPages= reader.getNumberOfPages();
for (int i = 1; i <= numberOfPages; i++) {
     PdfContentByte over = stamper.getOverContent(i);
     over.saveState();
     PdfGState gs = new PdfGState();
     gs.setFillOpacity(0.5f);
     over.setGState(gs);
     ColumnText.showTextAligned(over, Element.ALIGN_CENTER, p, 330, 450, 45);
     over.restoreState();
}
于 2017-08-22T16:09:38.040 回答