Marcin Sokolowski
Marcin Sokolowski

Reputation: 669

Creating document in iText without specyfing output

I went through few examples of iText library. I'm confused about creating the document, in typical example I saw:

Document document = new Document(PageSize.A4, 50, 50, 50, 50);
PdfWriter.getInstance(document, new FileOutputStream(PATH));
document.open();
//document.addSomeContent();
document.close();

Why is document bound to the file/output-stream from the beginning? Is it possible to create Document and when it will be finished, then save it , send to file/output_stream?

I looked into the sources, and getInstance() is:

public static PdfWriter getInstance(final Document document, final OutputStream os)
throws DocumentException {
    PdfDocument pdf = new PdfDocument();
    document.addDocListener(pdf);
    PdfWriter writer = new PdfWriter(pdf, os);
    pdf.addWriter(writer);
    return writer;
}

Connection:

Document  < --- > PdfDocument 
                      Λ
                      |
                      |
                      V
                 PdfWriter   < ---- > OutputStream

Just after creation of Document it is bound with PdfWriter and OutputStream. It is possible something like this:

Document document = new Document(PageSize.A4, 50, 50, 50, 50);
// document.addSomeContent();
document.save(someOutputStreamObject);

I would like to get rid of files and persistence and concentrate on creating logical structure of document. Later I would like pass the Document object to other module, which will be responsible for saving document to file or send as http response or whatever

Upvotes: 0

Views: 2330

Answers (1)

mkl
mkl

Reputation: 95918

Why is document bound to the file/output-stream from the beginning?

Because data can be written there from the beginning.

Generally you don't want to build the whole PDF document in memory and only in the end flush it all to a stream. Especially in case of server side solutions you have to consider situations in which you create many such documents concurrently. Even if there is enough memory for one or even a few documents, keeping hundreds or even thousands of them completely in memory at the same time would drain resources considerably.

Additionally serving the file while you still create it can prevent other problems, too. As Bruno says in his comment:

The session would time out before the document was finished. So I created iText using the builder pattern, feeding bytes to the OutputStream continuously to prevent server/browser time-outs

Instead you, therefore, want to write it as soon as possible. And this requires the output stream to be present from the start.

other module, which will be responsible for saving document to file or send as http response or whatever

As you seem to not suffer from resource restrictions, you can stream the data to a ByteArrayOutputStream and then forward the resulting byte array or some input stream or data source based on it.

If resources do matter, though, consider using pipelining with piped input and output streams for modularization.

Upvotes: 3

Related Questions