1 31 package org.pdfbox.examples.persistence; 32 33 import java.io.IOException ; 34 35 import java.util.Iterator ; 36 import java.util.List ; 37 38 import org.pdfbox.cos.COSBase; 39 import org.pdfbox.cos.COSDictionary; 40 import org.pdfbox.cos.COSName; 41 import org.pdfbox.cos.COSArray; 42 import org.pdfbox.cos.COSNumber; 43 import org.pdfbox.cos.COSInteger; 44 import org.pdfbox.cos.COSStream; 45 46 import org.pdfbox.pdmodel.PDDocument; 47 import org.pdfbox.pdmodel.PDDocumentInformation; 48 import org.pdfbox.pdmodel.PDPage; 49 50 import org.pdfbox.pdmodel.common.PDStream; 51 52 import org.pdfbox.exceptions.COSVisitorException; 53 54 60 public class AppendDoc 61 { 62 65 public AppendDoc() 66 { 67 super(); 68 } 69 79 public void appendDocument(PDDocument destination, PDDocument source) throws IOException 80 { 81 if( destination.isEncrypted() ) 82 { 83 throw new IOException ( "Error: destination PDF is encrypted, can't append encrypted PDF documents." ); 84 } 85 if( source.isEncrypted() ) 86 { 87 throw new IOException ( "Error: destination PDF is encrypted, can\'t append encrypted PDF documents." ); 88 } 89 PDDocumentInformation destInfo = destination.getDocumentInformation(); 90 PDDocumentInformation srcInfo = source.getDocumentInformation(); 91 destInfo.getDictionary().mergeInto( srcInfo.getDictionary() ); 92 93 COSDictionary destTrailer = destination.getDocument().getTrailer(); 94 COSDictionary destRoot = (COSDictionary)destTrailer.getDictionaryObject( COSName.ROOT ); 95 96 COSDictionary srcTrailer = source.getDocument().getTrailer(); 97 COSDictionary srcRoot = (COSDictionary)srcTrailer.getDictionaryObject( COSName.ROOT ); 98 99 COSName openAction = COSName.getPDFName( "OpenAction" ); 100 if( destRoot.getDictionaryObject( openAction ) == null ) 101 { 102 COSBase open = srcRoot.getDictionaryObject( openAction ); 103 if( open != null ) 104 { 105 destRoot.setItem( openAction, open ); 106 } 107 } 108 109 COSName acroForm = COSName.getPDFName( "AcroForm" ); 110 COSArray destAcroForm = (COSArray)destRoot.getDictionaryObject( acroForm ); 111 COSArray srcAcroForm = (COSArray)srcRoot.getDictionaryObject( acroForm ); 112 if( srcAcroForm != null ) 113 { 114 if( destAcroForm == null ) 115 { 116 destRoot.setItem( acroForm, srcAcroForm ); 117 } 118 else 119 { 120 destAcroForm.addAll( srcAcroForm ); 121 } 122 } 123 124 COSName threads = COSName.getPDFName( "Threads" ); 125 COSArray destThreads = (COSArray)destRoot.getDictionaryObject( threads ); 126 COSArray srcThreads = (COSArray)srcRoot.getDictionaryObject( threads ); 127 if( srcThreads != null ) 128 { 129 if( destThreads == null ) 130 { 131 destRoot.setItem( threads, srcThreads ); 132 } 133 else 134 { 135 destThreads.addAll( srcThreads ); 136 } 137 } 138 139 COSName names = COSName.getPDFName( "Names" ); 140 COSDictionary destNames = (COSDictionary)destRoot.getDictionaryObject( names ); 141 COSDictionary srcNames = (COSDictionary)srcRoot.getDictionaryObject( names ); 142 if( srcNames != null ) 143 { 144 if( destNames == null ) 145 { 146 destRoot.setItem( names, srcNames ); 147 } 148 else 149 { 150 destNames.mergeInto( srcNames ); 152 } 153 } 154 155 COSName outlines = COSName.getPDFName( "Outlines" ); 156 COSDictionary destOutlines = (COSDictionary)destRoot.getDictionaryObject( outlines ); 157 COSDictionary srcOutlines = (COSDictionary)srcRoot.getDictionaryObject( outlines ); 158 if( srcOutlines != null && destOutlines == null ) 159 { 160 destRoot.setItem( outlines, srcOutlines ); 161 } 162 163 COSName pagemode = COSName.getPDFName( "PageMode" ); 164 COSBase srcPageMode = srcRoot.getDictionaryObject( pagemode ); 165 if( srcOutlines != null && destOutlines == null ) 166 { 167 destRoot.setItem( pagemode, srcPageMode ); 168 } 169 170 COSName pageLabels = COSName.getPDFName( "PageLabels" ); 171 COSDictionary destLabels = (COSDictionary)destRoot.getDictionaryObject( pageLabels ); 172 COSDictionary srcLabels = (COSDictionary)srcRoot.getDictionaryObject( pageLabels ); 173 if( srcLabels != null ) 174 { 175 int destPageCount = destination.getPageCount(); 176 COSArray destNums = null; 177 if( destLabels == null ) 178 { 179 destLabels = new COSDictionary(); 180 destNums = new COSArray(); 181 destLabels.setItem( COSName.getPDFName( "Nums" ), destNums ); 182 destRoot.setItem( pageLabels, destLabels ); 183 } 184 else 185 { 186 destNums = (COSArray)destLabels.getDictionaryObject( COSName.getPDFName( "Nums" ) ); 187 } 188 COSArray srcNums = (COSArray)srcLabels.getDictionaryObject( COSName.getPDFName( "Nums" ) ); 189 for( int i=0; i<srcNums.size(); i+=2 ) 190 { 191 COSNumber labelIndex = (COSNumber)srcNums.getObject( i ); 192 long labelIndexValue = labelIndex.intValue(); 193 destNums.add( new COSInteger( labelIndexValue + destPageCount ) ); 194 destNums.add( srcNums.getObject( i+1 ) ); 195 } 196 } 197 198 COSName metadata = COSName.getPDFName( "Metadata" ); 199 COSStream destMetadata = (COSStream)destRoot.getDictionaryObject( metadata ); 200 COSStream srcMetadata = (COSStream)srcRoot.getDictionaryObject( metadata ); 201 if( destMetadata == null && srcMetadata != null ) 202 { 203 PDStream newStream = new PDStream( destination, srcMetadata.getUnfilteredStream(), false ); 204 newStream.getStream().mergeInto( srcMetadata ); 205 newStream.addCompression(); 206 destRoot.setItem( metadata, newStream ); 207 } 208 209 List pages = source.getDocumentCatalog().getAllPages(); 211 Iterator pageIter = pages.iterator(); 212 while( pageIter.hasNext() ) 213 { 214 PDPage page = (PDPage)pageIter.next(); 215 destination.addPage( page ); 216 } 217 } 218 219 229 public void doIt(String in1, String in2, String out) throws IOException , COSVisitorException 230 { 231 PDDocument doc1 = null; 232 PDDocument doc2 = null; 233 try 234 { 235 doc1 = PDDocument.load( in1 ); 236 doc2 = PDDocument.load( in2 ); 237 238 appendDocument(doc1, doc2); 239 doc1.save( out ); 240 } 241 catch( Exception e ) 242 { 243 e.printStackTrace(); 244 } 245 finally 246 { 247 close( doc1 ); 248 close( doc2 ); 249 } 250 } 251 252 private void close( PDDocument doc ) throws IOException 253 { 254 if( doc != null ) 255 { 256 doc.close(); 257 } 258 } 259 260 267 public static void main(String [] args) 268 { 269 AppendDoc app = new AppendDoc(); 270 try 271 { 272 if( args.length != 3 ) 273 { 274 app.usage(); 275 } 276 else 277 { 278 app.doIt( args[0], args[1], args[2]); 279 } 280 } 281 catch( Exception e ) 282 { 283 e.printStackTrace(); 284 } 285 } 286 289 private void usage() 290 { 291 System.err.println( "usage: " + this.getClass().getName() + " <input-file1> <input-file2> <output-file>" ); 292 } 293 } | Popular Tags |