Hi all,

I am developing a program to Brazilian Post Mail Office "ECT - Empresa Brasileira de Correios e Telégrafos". Congratulations to Bruno and Paulo. You may add ECT to your list of huge companies which use iText. I'm proud of trying to spread iText use inside this company.

Well, I'm developing a small program to process existing PDF documents. This program should process corporate documents adding a Cover-Page before their first page and adding a watermark in the upper right corner of each other page except the Cover-Page itself. Pretty simple, huh? These three documents (original document, standard cover-page and standard watermark) are all PDF files themselves. Also, the cover-page and the watermark-page are pre-determined in the program preferences. The only dinamic input is the original document.

So I actually and successfully completed the first version of the program. It worked pretty fine in the first developer tests. However, when I tried and processed real-life documents I noticed a very high memory usage as well as a really long document-processing time. These real-life documents have sizes ranging from 1Mb to 10Mb each.

After that I studied my program so I could discover any performance issues. As a matter of fact, I realized that there was indeed a problem in the approach I've taken.

Here are two methods that implement respectively the "Add Cover-Page" and "Add Watermark" features:

    private void addCoverPage(PdfReader documentPDF, String tempFileName) throws IOException,
            DocumentException {
        // Number of Pages
        int numPages = documentPDF.getNumberOfPages();

        // Create PdfCopy
        Document document = new Document();
        PdfCopy copy = new PdfCopy(document, new FileOutputStream(tempFileName));
        document.open();

        // Adds Cover-Page to the copy
        PdfImportedPage coverPage = copy.getImportedPage(coverPDF, 1);
        copy.addPage(coverPage);

        // Adds the original document's pages to the copy
        for (int i = 1; i <= numPages; i++) {
            PdfImportedPage currentPage = copy.getImportedPage(documentPDF, i);
            copy.addPage(currentPage);
        }

        // Copies acro form
        copy.copyAcroForm(coverPDF);

        document.close();
        copy.close();
        documentPDF.close();

        // Deletes original file and renames tempfile into the original filename
        moveTempFileIntoOriginalFile(tempFileName, fileName);
    }

    private void addWatermark(PdfReader documentPDF, String tempFileName) throws FileNotFoundException,
            DocumentException, IOException {
        // Number of Pages in original document
        int numPages = documentPDF.getNumberOfPages();

        // Gets PdfStamper
        PdfStamper stamper = new PdfStamper(documentPDF, new FileOutputStream(tempFileName));

        // Retrieves the watermark page from the watermark pdf file
        PdfImportedPage watermarkPage = stamper.getImportedPage(watermark, 1);
        Rectangle watermarkSize = watermark.getPageSize(1);

        // Adds the watermark
        PdfContentByte content = null;
        PdfContentByte contentOver = null;

        for (int i = 2; i <= numPages; i++) {
            // Adds the watermark into the top right corner of each page
            PdfContentByte pageContentOver = stamper.getOverContent(i);
            Rectangle pageSize = documentPDF.getPageSizeWithRotation(i);
            pageContentOver.addTemplate(watermarkPage, pageSize.width() - watermarkSize.width(), pageSize.height()
                    - watermarkSize.height());
        }

        stamper.close();
        documentPDF.close();

        // Deletes original file and renames tempfile into the original filename
        moveTempFileIntoOriginalFile(tempFileName, fileName);
    }


Ok. So I use PdfCopy to create a new document (call doc #2) and copy the cover-page and all original document's (call doc #1) pages into it. I need a PdfReader to read the cover page and another PdfReader to read the Original Document. The result is the original document with a standard cover-page inserted. Then I use PdfStamper to add the watermark sign into all pages. Note that PdfStamper will read from doc #2 and will be generating a doc #3. The problem is that this watermark has to be added to the document resulting from the PdfCopy process. So, after adding the cover-page to the document, PdfCopy creates a new document. Therefore, I use a new PdfReader to read this new document produced by PdfCopy. Then I use PdfStamper to add the watermark, generating the new doc #3.

If it sounds confusing, let's put it simple: The problem is that I must read a document (doc 1) to add a cover-page. This process generates a new document (doc 2). Since I also must add a watermark, I read this document (doc 2) and create a new document again (doc 3).

I also noted that the major performance issues were at the PdfReader creation process. So, my program is twice as slow because I must read the document twice. After that I tried a new approach. This time my intention is to find some way to read the original document and add the cover-page and watermark in the same process, so I can generate only one final file. The problem is that I can't find a way to add a cover-page (and copy it's acroform into the new document) and add the watermark into all pages using the same process. The more I study iText API the less I can find it.

At last, is there any way to use the same process(PdfCopy, PdfWriter or PdfStamper) to add both cover-page and watermark (from differente PDF files) into some original file? What can I do so as not to PdfRead the document twice?

I'm sorry for this really long post.

Thank you all in advance,

--
Filipe Fedalto

Cansado dos disparates e despautérios da República?
Quer um basta nas desventuras de nossos governantes?
Acesse http://www.monarquia.org.br e http://www.brasilimperial.org.br
e saiba mais a respeito.

Reply via email to