当使用 ByteArrayOutputStream 时,Itext PdfStamper getOverContent returns null
Itext PdfStamper getOverContent returns null when ByteArrayOutputStream used
我正在处理 pdf 文件。我需要在现有的 pdf 文件上添加水印。这就是为什么,我写了下面的代码。当我使用 FileOutputStream 时它工作得很好,但我需要使用 ByteArrayOutputStream 因为我的数据来自数据库并且我需要将它保存为字节数组。问题从这里开始。当我使用 PdfStamper returns null 的 ByteArrayOutputStream getOvercontent 方法时。我该如何处理?提前致谢。
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();
}
这是禁止的:
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(bytes.length);
outputStream.write(bytes, 0, bytes.length);
PdfStamper stamper = new PdfStamper(reader, outputStream);
您创建了一个名为 outputStream
的 OutputStream
,并且您似乎将一个完整的现有 PDF 复制到那个 OutputStream
(使用 write()
)。然后,您似乎打算通过将相同的 OutputStream
传递给 PdfStamper
实例,向 OutputStream
添加另一个完整的 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();
}
我正在处理 pdf 文件。我需要在现有的 pdf 文件上添加水印。这就是为什么,我写了下面的代码。当我使用 FileOutputStream 时它工作得很好,但我需要使用 ByteArrayOutputStream 因为我的数据来自数据库并且我需要将它保存为字节数组。问题从这里开始。当我使用 PdfStamper returns null 的 ByteArrayOutputStream getOvercontent 方法时。我该如何处理?提前致谢。
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();
}
这是禁止的:
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(bytes.length);
outputStream.write(bytes, 0, bytes.length);
PdfStamper stamper = new PdfStamper(reader, outputStream);
您创建了一个名为 outputStream
的 OutputStream
,并且您似乎将一个完整的现有 PDF 复制到那个 OutputStream
(使用 write()
)。然后,您似乎打算通过将相同的 OutputStream
传递给 PdfStamper
实例,向 OutputStream
添加另一个完整的 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();
}