/** 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(); }
void addDocument(PdfReader reader) throws DocumentException, IOException { if (!reader.isOpenedWithFullPermissions()) throw new BadPasswordException( MessageLocalization.getComposedMessage("pdfreader.not.opened.with.owner.password")); openDoc(); if (readers2intrefs.containsKey(reader)) { reader = new PdfReader(reader); } else { if (reader.isTampered()) throw new DocumentException( MessageLocalization.getComposedMessage("the.document.was.reused")); reader.consolidateNamedDestinations(); reader.setTampered(true); } reader.shuffleSubsetNames(); readers2intrefs.put(reader, new IntHashtable()); readers.add(reader); int len = reader.getNumberOfPages(); IntHashtable refs = new IntHashtable(); for (int p = 1; p <= len; ++p) { refs.put(reader.getPageOrigRef(p).getNumber(), 1); reader.releasePage(p); } pages2intrefs.put(reader, refs); visited.put(reader, new IntHashtable()); AcroFields acro = reader.getAcroFields(); // when a document with NeedAppearances is encountered, the flag is set // in the resulting document. boolean needapp = !acro.isGenerateAppearances(); if (needapp) needAppearances = true; fields.add(acro); updateCalculationOrder(reader); }
/** * Retrieves the page labels from a PDF as an array of String objects. * * @param reader a PdfReader object that has the page labels you want to retrieve * @return a String array or <code>null</code> if no page labels are present */ public static String[] getPageLabels(PdfReader reader) { int n = reader.getNumberOfPages(); PdfDictionary dict = reader.getCatalog(); PdfDictionary labels = (PdfDictionary) PdfReader.getPdfObjectRelease(dict.get(PdfName.PAGELABELS)); if (labels == null) return null; String[] labelstrings = new String[n]; HashMap<Integer, PdfObject> numberTree = PdfNumberTree.readTree(labels); int pagecount = 1; Integer current; String prefix = ""; char type = 'D'; for (int i = 0; i < n; i++) { current = Integer.valueOf(i); if (numberTree.containsKey(current)) { PdfDictionary d = (PdfDictionary) PdfReader.getPdfObjectRelease(numberTree.get(current)); if (d.contains(PdfName.ST)) { pagecount = ((PdfNumber) d.get(PdfName.ST)).intValue(); } else { pagecount = 1; } if (d.contains(PdfName.P)) { prefix = ((PdfString) d.get(PdfName.P)).toUnicodeString(); } if (d.contains(PdfName.S)) { type = ((PdfName) d.get(PdfName.S)).toString().charAt(1); } else { type = 'e'; } } switch (type) { default: labelstrings[i] = prefix + pagecount; break; case 'R': labelstrings[i] = prefix + RomanNumberFactory.getUpperCaseString(pagecount); break; case 'r': labelstrings[i] = prefix + RomanNumberFactory.getLowerCaseString(pagecount); break; case 'A': labelstrings[i] = prefix + RomanAlphabetFactory.getUpperCaseString(pagecount); break; case 'a': labelstrings[i] = prefix + RomanAlphabetFactory.getLowerCaseString(pagecount); break; case 'e': labelstrings[i] = prefix; break; } pagecount++; } return labelstrings; }
void addDocument(PdfReader reader, List<Integer> pagesToKeep) throws DocumentException, IOException { if (!readers2intrefs.containsKey(reader) && reader.isTampered()) throw new DocumentException( MessageLocalization.getComposedMessage("the.document.was.reused")); reader = new PdfReader(reader); reader.selectPages(pagesToKeep); if (reader.getNumberOfPages() == 0) return; reader.setTampered(false); addDocument(reader); }
PdfImportedPage getImportedPage(int pageNumber) { if (!reader.isOpenedWithFullPermissions()) throw new IllegalArgumentException("PdfReader not opened with owner password"); if (pageNumber < 1 || pageNumber > reader.getNumberOfPages()) throw new IllegalArgumentException("Invalid page number: " + pageNumber); Integer i = new Integer(pageNumber); PdfImportedPage pageT = (PdfImportedPage) importedPages.get(i); if (pageT == null) { pageT = new PdfImportedPage(this, writer, pageNumber); importedPages.put(i, pageT); } return pageT; }
/** 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; }
public static HashMap getNamedDestination(PdfReader reader, boolean fromNames) { IntHashtable pages = new IntHashtable(); int numPages = reader.getNumberOfPages(); for (int k = 1; k <= numPages; ++k) pages.put(reader.getPageOrigRef(k).getNumber(), k); HashMap names = fromNames ? reader.getNamedDestinationFromNames() : reader.getNamedDestinationFromStrings(); for (Iterator it = names.entrySet().iterator(); it.hasNext(); ) { Map.Entry entry = (Map.Entry) it.next(); ArrayList arr = ((PdfArray) entry.getValue()).getArrayList(); StringBuffer s = new StringBuffer(); try { s.append(pages.get(((PdfIndirectReference) arr.get(0)).getNumber())); s.append(' ').append(arr.get(1).toString().substring(1)); for (int k = 2; k < arr.size(); ++k) s.append(' ').append(arr.get(k).toString()); entry.setValue(s.toString()); } catch (Exception e) { it.remove(); } } return names; }
/** * Concatenates a PDF document selecting the pages to keep. The pages are described as ranges. The * page ordering can be changed but no page repetitions are allowed. * * @param reader the PDF document * @param ranges the comma separated ranges as described in {@link SequenceList} * @throws DocumentException on error */ public void addDocument(PdfReader reader, String ranges) throws DocumentException, IOException { fc.addDocument(reader, SequenceList.expand(ranges, reader.getNumberOfPages())); }