# iText PDF-Generierung ohne Speichern



## lieschen89 (27. Nov 2013)

Hi,

ich möchte mittels iText PDFs generieren, die aber nirgends gespeichert, sondern nur angezeigt werden.
Wie das für Webanwendungen geht habe ich schon gefunden:
java - Creating a PDF using iText without saving it to a temp file - Stack Overflow
Aber ich habe eine normale Desktop-Anwendung mit Swing.

Weiß jemand ob das geht?

Also das hier, nur ohne Pfad:

```
PdfWriter.getInstance(document, new FileOutputStream(SPEICHER_PFAD));
```


----------



## rme (27. Nov 2013)

Hallo,

das geht genau wie in der Lösung, die in dem verlinkten Beitrag erwähnt wurde: Da getInstance anscheinend als zweiten Parameter einen OutputStream erwartet, kannst du auch einen ByteArrayOutputstream nehmen. Dann hast du die PDF-Datei danach in einem byte-Array und brauchst nur noch eine Komponente, die eine PDF aus einem byte-Array oder einem InputStream heraus anzeigen kann


----------



## lieschen89 (27. Nov 2013)

> und brauchst nur noch eine Komponente, die eine PDF aus einem byte-Array oder einem InputStream heraus anzeigen kann



ok danke, aber danach hatte ich gegoogelt, aber nichts gefunden. Bzw immer nur sowas hier:
Need to create PDF from bytearray (Java) - Stack Overflow
Oder eben so Antworten wie, wie will man ein PDF erzeugen, ohne dass es existiert...

Also wie würde man das genau machen?


----------



## rme (27. Nov 2013)

Als erstes brauchst du einen ByteArrayOutputStream, um die PDF-Daten darin zu speichern:

```
ByteArrayOutputStream pdfByteStream = new ByteArrayOutputStream();
```

Mit diesem kannst du dann iText initialisieren:


```
Document document = new Document();
PdfWriter.getInstance(document, pdfByteStream);
document.open();
```

Danach kannst du auf document arbeiten und der Inhalt von pdfByteStream wird angepasst. Womit möchtest du die PDF-Daten später anzeigen? Davon hängt es ab, was als nächstes kommt


----------



## lieschen89 (27. Nov 2013)

> Womit möchtest du die PDF-Daten später anzeigen?



Ganz normal mit dem Adobe Reader.

(Im Moment mache ich das (also mit nem gespeichertem PDF-File) über:

```
Desktop.getDesktop().open(pdfFile);
```
)


----------



## rme (27. Nov 2013)

Der Adobe-Reader kann aber nur Dateien öffnen, die tatsächlich existieren. Du müsstest also eine temporäre Datei erzeugen und könntest diese im Adobe-Reader anzeigen. Wenn du sie nicht speicherst, existiert sie ja nur innerhalb deines Programms und darauf kann der Reader nicht zugreifen. Oder habe ich deine Anforderung falsch verstanden?


----------



## lieschen89 (27. Nov 2013)

ah ok. Kenn das nur von Word, hatte das da gleich gesetzt, von wegen ich erstell ne Neue Datei. Die ist ja auch noch nirgends gespeichert. Sondern erst wenn man auf 'Speichern unter' klickt. Dachte im Adobe läuft das ähnlich.

Ja ok, weiß nicht, eigentlich wollte ich das schon im Adobe öffnen.

Das PDF sollte halt wenn möglich gedruckt werden können und die Möglichkeit das manuell dann abzuspeichern, falls mans doch speichern möchte in manchen Fällen, bräuchte ich eigentlich schon.
Zoomen wäre nicht schlecht. Aber nicht unbedingt notwendig.

Was gibts denn für Alternativen?

Wenn nicht dann muss ich es halt doch iwo zwischenspeichern.


----------



## rme (27. Nov 2013)

Die Alternative wäre, dass du die Datei innerhalb deines Java-Programms anzeigt. Das ist aber kompliziert und für den Nutzer ungewohnt, weil sich dann nicht sein gewohntes Werkzeug zum Betrachten von PDF-Dateien öffnet.

Aber wenn du eine temporäre Datei erzeugst, bekommt der Nutzer davon ja gar nichts mit - du kannst sie an einem temporären Ort speichern, ohne den Nutzer nach einem Dateinamen oder so zu fragen und dann einfach den Reader öffnen lassen. Für den Benutzer ist es dann so, dass er auf einen Button in deinem Programm klickt, dort die Datei erzeugt und temporär gespeichert wird (merkt er nicht) und sich dann der Reader öffnet. Von da kann er dann mit Speichern Unter die Datei abspeichern, direkt drucken oder andere Wünsche mit ihr ausleben.

Welche Bedenken hast du bei diesem Vorgehen?


----------



## lieschen89 (27. Nov 2013)

Ja, das Problem ist der Mehraufwand und dass es 'eleganter' wäre ohne Temp-File unter den unten stehenden Gesichtspunkten. 

Wenn der Benutzer z.B. sich ein PDF generieren lässt, dieses aber nicht schließt und sich noch mal eins generieren lassen möchte (und ich einen fixen Speicherort habe, z.B. C:/temp/meinpdf.pdf) dann steigt das Programm aus und bringt einen Fehler, weil ja ein gerade geöffnete Datei geändert werden soll.
Das muss ja dann iwie gelöst werden.

Entweder durch eine Fehlermeldung die dem Benutzer sagt er soll die Datei schließen (unschön, dann kann er immer nur 1 PDF haben und er denkt sich, was ist dass den fürn quatsch)

Oder man macht das mit mehreren Temp-Files und vergibt die Dateinamen dynamisch (pdf1 pdf2....).
Was aber zu einem riesigem Temp-Ordner führt, der ja irgenwann auch wieder geleert werden muss.
Für den Benutzer wäre aber diese Variante, finde ich, wahrscheinlich die komfortabelste.

Aber ich denke auf den Reader will ich nicht verzichten. Werde wohl dann iwie Möglichkeit 2 umsetzen.

Aber trotzdem vielen dank.


----------



## rme (27. Nov 2013)

Dafür gibt es zwei Tricks:

* benutze File.createTempFile("rechnung", ".pdf", null). Dadurch wird eine Datei mit einem zufälligen Namen, der mit "rechnung" beginnt und mit ".pdf" endet, in einem temporären Verzeichnis erzeugt. Die Methode kannst du beliebig oft aufrufen, es wird immer eine passende Datei erstellt und zurückgeliefert

* rufe die Methode deleteOnExit() auf dem erhaltenen File-Objekt auf. Dadurch wird die Datei gelöscht, sobald dein Programm beendet wird - aber nur, wenn sie im Reader auch bereits geschlossen wurde. Ansonsten kümmert sich das Betriebssystem in regelmäßigen Abständen darum, dass der Ort geleert wird, da createTempFile die Datei an einem Ort erzeugt, der aufgeräumt wird.

Du siehst, alles wird gut


----------



## lieschen89 (27. Nov 2013)

ah, supi danke, das ist ja klasse.

Ok, damit haben sich meine Probleme dann gelöst ;-)


----------

