2017-08-22 2 views
0

Ich arbeite an einer PDF-Datei. Ich muss ein Wasserzeichen auf einer bestehenden PDF-Datei hinzufügen. Deshalb habe ich folgenden Code geschrieben. Wenn ich FileOutputStream verwendet, funktioniert es perfekt, aber ich muss ByteArrayOutputStream verwenden, weil meine Daten aus der Datenbank kommen und ich es als Byte-Array speichern muss. Das Problem beginnt hier. Wenn ich die Methode ByteArrayOutputStream verwende, gibt die Methode getOvercontent von PdfStamper null zurück. Wie kann ich damit umgehen? Danke im Voraus. Itext PdfStamper getOverContent gibt null zurück, wenn ByteArrayOutputStream verwendet

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

Und die alte Version von Code ist dies.

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

Antwort

1

Dies ist verboten:

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

Sie ein OutputStream erstellen, mit dem Namen outputStream, und es scheint, dass Sie einen ausgewachsenen bestehenden PDF zu diesen OutputStream (mit write()) kopieren. Dann scheinen Sie die Absicht zu haben, eine weitere vollständige PDF zu dieser OutputStream hinzuzufügen, indem Sie dieselbe OutputStream an die PdfStamper Instanz übergeben. Das sollte zu einer beschädigten PDF-Datei führen.

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

Sie haben einen saveState() Operator, aber man kann nie restoreState() verwenden: in illegal PDF Syntax

Dies wird führen. Für jede saveState() sollten Sie eine restoreState() haben. Ihr saveState() ist in der falschen Position! Es ist, als ob Sie nicht wissen, was saveState() und restoreState() sind.

Schließlich beginnen Sie mit dem Zählen einer 0, aber die erste Seite ist Seite 1, nicht Seite 0. Daher ist for (int i = 0; i < numberOfPages; i++) falsch. Es sollte for (int i = 1; i <= numberOfPages; i++) sein. Dieser Fehler verursacht over als null.

Dies ist ein Versuch, den Code zu beheben:

// 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

danken für Ihre Hilfe. Es war sehr schmerzhaft 5 Stunden. –