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.
- [iText-questions] Algorithm problem - use of PdfCopy and Pd... Filipe Fedalto
- Re: [iText-questions] Algorithm problem - use of PdfCo... Paulo Soares
- Re: [iText-questions] Algorithm problem - use of P... Filipe Fedalto
- Re: [iText-questions] Algorithm problem - use ... Filipe Fedalto
- Re: [iText-questions] Algorithm problem - ... Bruno Lowagie
