/** * Copyright (C) 2008-2010, Squale Project - http://www.squale.org * * This file is part of Squale. * * Squale is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the * License, or any later version. * * Squale is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Squale. If not, see <http://www.gnu.org/licenses/>. */ package org.squale.welcom.outils.pdf.advanced; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; import java.util.ArrayList; import java.util.Date; import java.util.Iterator; import java.util.List; import com.lowagie.text.Document; import com.lowagie.text.DocumentException; import com.lowagie.text.pdf.PRAcroForm; import com.lowagie.text.pdf.PdfCopy; import com.lowagie.text.pdf.PdfImportedPage; import com.lowagie.text.pdf.PdfReader; import com.lowagie.text.pdf.PdfStamper; import com.lowagie.text.pdf.SimpleBookmark; /** * @author M327837 Pour changer le mod�le de ce commentaire de type g�n�r�, allez � : * Fen�tre>Pr�f�rences>Java>G�n�ration de code>Code et commentaires */ public class WPdfMerge { /** dernier id (date du jour) */ private static long lastIdField = new Date().getTime(); /** le prefixe */ private static final String prefixField = "T"; /** la liste des readers */ private final ArrayList readers = new ArrayList(); /** l'outputstream */ private OutputStream out = null; /** le pdfDecoration */ private WPdfDecoration decoration = null; /** * @param pOut l'outputstream */ public WPdfMerge( final OutputStream pOut ) { out = pOut; } /** * @param reader le pdf reader */ public void add( final PdfReader reader ) { if ( reader != null ) { readers.add( reader ); } } /** * @param reader le reader * @throws IOException exception pouvant etre levee */ public void add( final byte[] reader ) throws IOException { if ( reader != null ) { readers.add( new PdfReader( reader ) ); } } /** * @throws DocumentException exception pouvant etre levee * @throws IOException exception pouvant etre levee */ public void close() throws DocumentException, IOException { byte[] theReport = merge(); if ( theReport != null ) { final byte[] filledReport = fillDecoration( new PdfReader( theReport ) ); if ( filledReport != null ) { theReport = filledReport; } // theReport=fillFooter(new PdfReader(theReport)); out.write( theReport ); } } /** * @param pdfReader le reader * @return decoration ajoutee * @throws DocumentException exception pouvant etre levee * @throws IOException exception pouvant etre levee */ private byte[] fillDecoration( final PdfReader pdfReader ) throws DocumentException, IOException { if ( decoration != null ) { return decoration.fill( pdfReader ); } else { return null; } } /** * merge * * @return byte array rempli */ private byte[] merge() { final ByteArrayOutputStream tmpout = new ByteArrayOutputStream(); int pageOffset = 0; int f = 0; Document document = null; final ArrayList master = new ArrayList(); PdfCopy writer = null; final Iterator it = readers.iterator(); while ( it.hasNext() ) { PdfReader reader = (PdfReader) it.next(); try { // Renome tout les champs; reader = new PdfReader( renameFieldUnique( reader ) ); reader.consolidateNamedDestinations(); // we retrieve the total number of pages final int n = reader.getNumberOfPages(); final List bookmarks = SimpleBookmark.getBookmark( reader ); if ( bookmarks != null ) { if ( pageOffset != 0 ) { SimpleBookmark.shiftPageNumbers( bookmarks, pageOffset, null ); } master.addAll( bookmarks ); } pageOffset += n; if ( f == 0 ) { // step 1: creation of a document-object document = new Document( reader.getPageSizeWithRotation( 1 ) ); // step 2: we create a writer that listens to the document writer = new PdfCopy( document, tmpout ); // step 3: we open the document document.open(); } // step 4: we add content PdfImportedPage page; for ( int i = 0; i < n; ) { ++i; page = writer.getImportedPage( reader, i ); writer.addPage( page ); } final PRAcroForm form = reader.getAcroForm(); if ( form != null ) { writer.copyAcroForm( reader ); } f++; if ( master.size() > 0 ) { writer.setOutlines( master ); } // step 5: we close the document // document.close(); } catch ( final Exception e ) { e.printStackTrace(); } } if ( document != null ) { document.close(); } return tmpout.toByteArray(); } /** * Renomme tous le champs du pdf avoir qu'il soit tous uniques * * @param pdfReader le reader * @return les champs renommes * @throws DocumentException exception pouvant etre levee * @throws IOException exception pouvant etre levee */ private byte[] renameFieldUnique( final PdfReader pdfReader ) throws DocumentException, IOException { final ByteArrayOutputStream pOut = new ByteArrayOutputStream(); final PdfStamper pdfStamper = new PdfStamper( pdfReader, pOut ); if ( pdfReader.getAcroForm() != null ) { for ( int i = 0; i < pdfReader.getAcroForm().size(); i++ ) { final PRAcroForm.FieldInformation p = (PRAcroForm.FieldInformation) pdfReader.getAcroForm().getFields().get( i ); final String newName = WPdfMerge.getUniqueFieldName(); pdfStamper.getAcroFields().renameField( p.getName(), newName ); } } pdfStamper.close(); return pOut.toByteArray(); } /** * @return le nom du champ unique */ private synchronized static String getUniqueFieldName() { return prefixField + ( lastIdField++ ); } /** * @return decoration */ public WPdfDecoration getDecoration() { return decoration; } /** * @param pDecoration decoration */ public void setDecoration( final WPdfDecoration pDecoration ) { decoration = pDecoration; } }