/** Creates the new PDF by merging the fields and forms. */ protected void closeIt() throws IOException { for (int k = 0; k < readers.size(); ++k) { readers.get(k).removeFields(); } for (int r = 0; r < readers.size(); ++r) { PdfReader reader = readers.get(r); for (int page = 1; page <= reader.getNumberOfPages(); ++page) { pageRefs.add(getNewReference(reader.getPageOrigRef(page))); pageDics.add(reader.getPageN(page)); } } mergeFields(); createAcroForms(); for (int r = 0; r < readers.size(); ++r) { PdfReader reader = readers.get(r); for (int page = 1; page <= reader.getNumberOfPages(); ++page) { PdfDictionary dic = reader.getPageN(page); PdfIndirectReference pageRef = getNewReference(reader.getPageOrigRef(page)); PdfIndirectReference parent = root.addPageRef(pageRef); dic.put(PdfName.PARENT, parent); propagate(dic, pageRef, false); } } for (Map.Entry<PdfReader, IntHashtable> entry : readers2intrefs.entrySet()) { PdfReader reader = entry.getKey(); try { file = reader.getSafeFile(); file.reOpen(); IntHashtable t = entry.getValue(); int keys[] = t.toOrderedKeys(); for (int k = 0; k < keys.length; ++k) { PRIndirectReference ref = new PRIndirectReference(reader, keys[k]); addToBody(PdfReader.getPdfObjectRelease(ref), t.get(keys[k])); } } finally { try { file.close(); // TODO: Removed - the user should be responsible for closing all PdfReaders. But, this // could cause a lot of memory leaks in code out there that hasn't been properly closing // things - maybe add a finalizer to PdfReader that calls PdfReader#close() ?? // reader.close(); } catch (Exception e) { // empty on purpose } } } pdf.close(); }
/** extracts attachments from PDF File */ @SuppressWarnings("unchecked") protected Map extractAttachments(PdfReader reader) throws IOException { Map fileMap = new HashMap(); PdfDictionary catalog = reader.getCatalog(); PdfDictionary names = (PdfDictionary) PdfReader.getPdfObject(catalog.get(PdfName.NAMES)); if (names != null) { PdfDictionary embFiles = (PdfDictionary) PdfReader.getPdfObject(names.get(new PdfName("EmbeddedFiles"))); if (embFiles != null) { HashMap embMap = PdfNameTree.readTree(embFiles); for (Iterator i = embMap.values().iterator(); i.hasNext(); ) { PdfDictionary filespec = (PdfDictionary) PdfReader.getPdfObject((PdfObject) i.next()); Object fileInfo[] = unpackFile(reader, filespec); if (fileMap.containsKey(fileInfo[0])) { throw new RuntimeException(DUPLICATE_FILE_NAMES); } fileMap.put(fileInfo[0], fileInfo[1]); } } } for (int k = 1; k <= reader.getNumberOfPages(); ++k) { PdfArray annots = (PdfArray) PdfReader.getPdfObject(reader.getPageN(k).get(PdfName.ANNOTS)); if (annots == null) { continue; } for (Iterator i = annots.getArrayList().listIterator(); i.hasNext(); ) { PdfDictionary annot = (PdfDictionary) PdfReader.getPdfObject((PdfObject) i.next()); PdfName subType = (PdfName) PdfReader.getPdfObject(annot.get(PdfName.SUBTYPE)); if (!PdfName.FILEATTACHMENT.equals(subType)) { continue; } PdfDictionary filespec = (PdfDictionary) PdfReader.getPdfObject(annot.get(PdfName.FS)); Object fileInfo[] = unpackFile(reader, filespec); if (fileMap.containsKey(fileInfo[0])) { throw new RuntimeException(DUPLICATE_FILE_NAMES); } fileMap.put(fileInfo[0], fileInfo[1]); } } return fileMap; }
/** * Add an imported page to our output * * @param iPage an imported page * @throws IOException , BadPdfFormatException */ public void addPage(PdfImportedPage iPage) throws IOException, BadPdfFormatException { int pageNum = setFromIPage(iPage); PdfDictionary thePage = reader.getPageN(pageNum); PRIndirectReference origRef = reader.getPageOrigRef(pageNum); reader.releasePage(pageNum); RefKey key = new RefKey(origRef); PdfIndirectReference pageRef; IndirectReferences iRef = (IndirectReferences) indirects.get(key); if (iRef != null && !iRef.getCopied()) { pageReferences.add(iRef.getRef()); iRef.setCopied(); } pageRef = getCurrentPage(); if (iRef == null) { iRef = new IndirectReferences(pageRef); indirects.put(key, iRef); } iRef.setCopied(); PdfDictionary newPage = copyDictionary(thePage); root.addPage(newPage); ++currentPageNumber; }
/** * Create a page stamp. New content and annotations, including new fields, are allowed. The fields * added cannot have parents in another pages. This method modifies the PdfReader instance. * * <p>The general usage to stamp something in a page is: * * <p> * * <pre> * PdfImportedPage page = copy.getImportedPage(reader, 1); * PdfCopy.PageStamp ps = copy.createPageStamp(page); * ps.addAnnotation(PdfAnnotation.createText(copy, new Rectangle(50, 180, 70, 200), "Hello", "No Thanks", true, "Comment")); * PdfContentByte under = ps.getUnderContent(); * under.addImage(img); * PdfContentByte over = ps.getOverContent(); * over.beginText(); * over.setFontAndSize(bf, 18); * over.setTextMatrix(30, 30); * over.showText("total page " + totalPage); * over.endText(); * ps.alterContents(); * copy.addPage(page); * </pre> * * @param iPage an imported page * @return the <CODE>PageStamp</CODE> */ public PageStamp createPageStamp(PdfImportedPage iPage) { int pageNum = iPage.getPageNumber(); PdfReader reader = iPage.getPdfReaderInstance().getReader(); PdfDictionary pageN = reader.getPageN(pageNum); return new PageStamp(reader, pageN, this); }