2017-08-22 175 views
0

我正在使用PDF文件。我需要在現有的pdf文件上添加水印。這就是爲什麼,我寫了下面的代碼。當我使用FileOutputStream時,它完美地工作,但我需要使用ByteArrayOutputStream,因爲我的數據來自數據庫,我需要將它保存爲字節數組。問題從這裏開始。當我使用PdfStamper的ByteArrayOutputStream getOvercontent方法返回null時。我該如何處理?提前致謝。 當使用ByteArrayOutputStream時,Itext PdfStamper 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(); 
} 

回答

1

禁止

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++)。此錯誤是導致overnull的原因。

這是解決您的代碼嘗試:

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

感謝您的幫助。這是非常痛苦的5個小時。 –

相關問題