Erstellen einer PDF aus einer Vorlage in iterxsharp und Ausgabe als Inhaltsdisposition.

8

Ich würde gerne ein existierendes PDF öffnen, etwas Text hinzufügen und dann als Inhaltsdisposition mit itext sharp ausgeben. Ich habe den folgenden Code. Wo es herunterfällt, ist es, dass ich als Speicherstrom ausgeben möchte, aber filestream, um die ursprüngliche Datei zu öffnen.

Hier ist was ich habe. Offensichtlich funktioniert PdfWriter zweimal nicht.

%Vor%     
frosty 27.02.2012, 16:54
quelle

2 Antworten

13

Sie haben ein paar Probleme, bei denen ich versuchen werde, Sie zu begleiten.

Zunächst dient das Document -Objekt nur dazu, mit neuen PDFs zu arbeiten, ohne bestehende zu modifizieren. Im Grunde genommen ist das Document -Objekt ein Bündel von Wrapper-Klassen, die die zugrunde liegenden Teile der PDF-Spezifikation abstrahieren und es Ihnen ermöglichen, mit Dingen auf höherer Ebene wie Absätzen und Reflow-Inhalt zu arbeiten. Diese Abstraktionen verwandeln das, was Sie von "Absätzen" halten, in rohe Befehle, die den Absatz Zeile für Zeile ohne Beziehung zwischen Zeilen schreiben. Wenn Sie mit einem vorhandenen Dokument arbeiten, gibt es keinen sicheren Weg zu sagen, wie Sie Text umleiten, damit diese Abstraktionen nicht verwendet werden.

Stattdessen möchten Sie das Objekt PdfStamper verwenden. Wenn Sie mit diesem Objekt arbeiten, haben Sie zwei Möglichkeiten, mit potenziell überlappendem Inhalt zu arbeiten. Entweder wird Ihr neuer Text über vorhandenen Inhalt geschrieben oder Ihr Text wird darunter geschrieben. Die beiden Methoden GetOverContent() oder GetUnderContent() eines instanziierten PdfStamper -Objekts geben ein PdfContentByte -Objekt zurück, mit dem Sie dann Text schreiben können.

Es gibt zwei Möglichkeiten, Text zu schreiben, entweder manuell oder über ein ColumnText -Objekt. Wenn Sie HTML erstellt haben, können Sie sich das Objekt ColumnText so vorstellen, als ob Sie eine große Zeile mit fester Position und eine einzelne Spalte <TABLE> verwenden würden. Der Vorteil von ColumnText ist, dass Sie Abstraktionen höherer Ebenen wie Paragraph verwenden können.

Im Folgenden finden Sie eine voll funktionsfähige C # 2010 WinForms-App, die auf iTextSharp 5.1.2.0 abzielt und die oben genannten Vorteile bietet. Sehen Sie die Code-Kommentare für alle Fragen. Es sollte ziemlich einfach sein, dies in ASP.Net zu konvertieren.

%Vor%

Was Ihr zweites Problem mit FileStream vs MemoryStream angeht, so sehen Sie die Methodensignatur für fast jede Methode (eigentlich alle , soweit ich weiß) in iTextSharp Sie sehen, dass alle ein Objekt Stream und nicht nur ein Objekt FileStream verwenden. Jedes Mal, wenn Sie dies sehen, auch außerhalb von iTextSharp, bedeutet dies, dass Sie jede Unterklasse von Stream übergeben können, die das MemoryStream -Objekt enthält, alles andere bleibt gleich.

Der folgende Code ist eine leicht modifizierte Version des obigen. Ich habe die meisten Kommentare entfernt, um sie kürzer zu machen. Die wichtigste Änderung ist, dass wir MemoryStream anstelle von FileStream verwenden. Auch wenn wir mit der PDF fertig sind, wenn das Objekt PdfStamper vor dem Zugriff auf die rohen Binärdaten geschlossen werden muss. (Das using Statement wird dies später automatisch für uns tun, aber es schließt auch den Stream, also müssen wir es hier manuell machen.)

Eine andere Sache, niemals die Methode GetBuffer() von MemoryStream verwenden. Es klingt wie du willst (und ich habe es versehentlich auch benutzt), aber stattdessen willst du ToArray() benutzen. GetBuffer() enthält nicht initialisierte Bytes, die normalerweise beschädigte PDFs erzeugen. Statt in den HTTP-Antwort-Stream zu schreiben, speichere ich zuerst die Bytes im Array. Aus einer Debugging-Perspektive ermöglicht es mir, alle meine iTextSharp und% Co_de% -Code zu beenden und sicherzustellen, dass es korrekt ist, und dann tun, was ich will mit dem RAW-Byte-Array. In meinem Fall habe ich keinen Web-Server zur Hand, also schreibe ich sie auf die Festplatte, aber Sie könnten genauso einfach System.IO

aufrufen %Vor%     
Chris Haas 27.02.2012, 20:49
quelle
3

Der zweite Teil Ihres Fragentitels lautet:

  

"Ausgabe als Inhaltsdisposition"

Wenn Sie wirklich möchten, können Sie dies tun:

%Vor%

Die Verwendung von MemoryStream ist nicht erforderlich, da Response.OutputStream verfügbar ist. Ihr Beispielcode ruft NewPage() und nicht auf, um den Text zu einer vorhandenen Seite Ihrer PDF-Datei hinzuzufügen. Hier ist eine Möglichkeit, das zu tun, was Sie gefragt haben:

%Vor%

Ich denke, Sie haben bereits herausgefunden, dass die Kombination Document / PdfWriter in dieser Situation nicht funktioniert :) Dies ist die Standardmethode zum Erstellen eines neuen PDF-Dokuments.

    
kuujinbo 28.02.2012 20:11
quelle

Tags und Links