6.1 Use PdfReader to read PDF
Retrieve document and page information
D:/data/iText/inAction/chapter03/image_direct.pdf
Number of pages: 1
Size of page 1: [0.0,0.0,283.0,416.0]
Rotation of page 1: 0
Page size with rotation of page 1: Rectangle: 283.0×416.0 (rot: 0 degrees)
Is rebuilt? false
Is encrypted? false
import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintWriter; import com.itextpdf.text.DocumentException; import com.itextpdf.text.Rectangle; import com.itextpdf.text.pdf.PdfReader; public class PageInformation { /** The resulting text file with info about a PDF. */ public static final String RESULT = "D:/data/iText/inAction/chapter06/page_info.txt"; /** * Main method. * @param args no arguments needed * @throws DocumentException * @throwsIOException */ public static void main(String[] args) throws DocumentException, IOException { //Inspecting PDFs PrintWriter writer = new PrintWriter(new FileOutputStream(RESULT)); inspect(writer, "D:/data/iText/inAction/chapter03/image_direct.pdf"); writer.close(); } /** * Inspect a PDF file and write the info to a txt file * @param writer Writer to a text file * @param filename Path to the PDF file * @throwsIOException */ public static void inspect(PrintWriter writer, String filename) throws IOException { PdfReader reader = new PdfReader(filename); writer.println(filename); writer.print("Number of pages: "); writer.println(reader.getNumberOfPages()); Rectangle mediabox = reader.getPageSize(1); writer.print("Size of page 1: ["); writer.print(mediabox.getLeft()); writer.print(','); writer.print(mediabox.getBottom()); writer.print(','); writer.print(mediabox.getRight()); writer.print(','); writer.print(mediabox.getTop()); writer.println("]"); writer.print("Rotation of page 1: "); writer.println(reader.getPageRotation(1)); writer.print("Page size with rotation of page 1: "); writer.println(reader.getPageSizeWithRotation(1)); writer.print("Is rebuilt? "); writer.println(reader.isRebuilt()); writer.print("Is encrypted? "); writer.println(reader.isEncrypted()); writer.println(); writer.flush(); } }
Page Size page size
Corrupted PDF
Encrypted PDF
Use PdfReader to reduce memory
Partial read
/** * Do a full read of a PDF file * @param writer a writer to a report file * @param filename the file to read * @throwsIOException */ public static void fullRead(PrintWriter writer, String filename) throws IOException { long before = getMemoryUse(); PdfReader reader = new PdfReader(filename); reader.getNumberOfPages(); writer.println(String.format("Memory used by full read: %d", getMemoryUse() - before)); writer.flush(); } /** * Do a partial read of a PDF file * @param writer a writer to a report file * @param filename the file to read * @throwsIOException */ public static void partialRead(PrintWriter writer, String filename) throws IOException { long before = getMemoryUse(); PdfReader reader = new PdfReader( new RandomAccessFileOrArray(filename), null); reader.getNumberOfPages(); writer.println(String.format("Memory used by partial read: %d", getMemoryUse() - before)); writer.flush(); }
Select page
PdfReader.selectPages(“3”);
PdfReader.selectPages(“4-8”);
After executing selectPages(), the number of pages becomes the actual number of selected pages, so be careful about crossing the boundary.
import java.io.FileOutputStream; import java.io.IOException; import com.itextpdf.text.Document; import com.itextpdf.text.DocumentException; import com.itextpdf.text.pdf.PdfCopy; import com.itextpdf.text.pdf.PdfReader; import com.itextpdf.text.pdf.PdfStamper; public class SelectPages { /** A resulting PDF file. */ public static final String RESULT1 = "results/part2/chapter06/timetable_stamper.pdf"; /** A resulting PDF file. */ public static final String RESULT2 = "results/part2/chapter06/timetable_copy.pdf"; /** * Main method. * @param args no arguments needed * @throws DocumentException * @throwsIOException */ public static void main(String[] args) throws IOException, DocumentException { PdfReader reader = new PdfReader("D:/data/iText/inAction/chapter03/movie_posters.pdf"); reader.selectPages("4-8"); manipulateWithStamper(reader); manipulateWithCopy(reader); } /** * Creates a new PDF based on the one in the reader * @param reader a reader with a PDF file * @throwsIOException * @throws DocumentException */ private static void manipulateWithStamper(PdfReader reader) throws IOException, DocumentException { PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(RESULT1)); stamper.close(); } /** * Creates a new PDF based on the one in the reader * @param reader a reader with a PDF file * @throwsIOException * @throws DocumentException */ private static void manipulateWithCopy(PdfReader reader) throws IOException, DocumentException { int n = reader.getNumberOfPages(); Document document = new Document(); PdfCopy copy = new PdfCopy(document, new FileOutputStream(RESULT2)); document.open(); for (int i = 0; i < n;) { copy.addPage(copy.getImportedPage(reader, + + i)); } document.close(); } }
6.2 Copy pages from PDF
Import page
import java.io.FileOutputStream; import java.io.IOException; import com.itextpdf.text.Document; import com.itextpdf.text.DocumentException; import com.itextpdf.text.Image; import com.itextpdf.text.pdf.PdfImportedPage; import com.itextpdf.text.pdf.PdfPTable; import com.itextpdf.text.pdf.PdfReader; import com.itextpdf.text.pdf.PdfWriter; public class ImportingPages1 { /** The resulting PDF file. */ public static final String RESULT = "D:/data/iText/inAction/chapter06/time_table_imported1.pdf"; /** * Main method. * @param args no arguments needed * @throws DocumentException * @throwsIOException */ public static void main(String[] args) throws IOException, DocumentException { // step 1 Document document = new Document(); // step 2 PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(RESULT)); // step 3 document.open(); // step 4 PdfPTable table = new PdfPTable(2); PdfReader reader = new PdfReader("D:/data/iText/inAction/chapter03/movie_posters.pdf"); int n = reader.getNumberOfPages(); PdfImportedPage page; for (int i = 1; i <= n; i + + ) { page = writer.getImportedPage(reader, i); table.addCell(Image.getInstance(page)); } document.add(table); // step 5 document.close(); } }
Zoom and overlay pages
Overlay PDF page
import java.io.FileOutputStream; import java.io.IOException; import com.itextpdf.text.Document; import com.itextpdf.text.DocumentException; import com.itextpdf.text.Element; import com.itextpdf.text.Font; import com.itextpdf.text.Image; import com.itextpdf.text.PageSize; import com.itextpdf.text.Paragraph; import com.itextpdf.text.Font.FontFamily; import com.itextpdf.text.pdf.BaseFont; import com.itextpdf.text.pdf.PdfContentByte; import com.itextpdf.text.pdf.PdfGState; import com.itextpdf.text.pdf.PdfImportedPage; import com.itextpdf.text.pdf.PdfReader; import com.itextpdf.text.pdf.PdfWriter; public class Layers { /** The resulting PDF. */ public static final String SOURCE = "D:/data/iText/inAction/chapter06/layers_orig.pdf"; /** The resulting PDF. */ public static final String RESULT = "D:/data/iText/inAction/chapter06/layers.pdf"; /** The movie poster. */ public static final String RESOURCE = "E:/study/PDF/SourceCodeiText/itext-book/book/resources/img/loa.jpg"; /** * Main method. * @param args no arguments needed * @throws DocumentException * @throwsIOException */ public static void main(String[] args) throws IOException, DocumentException { new Layers().createPdf(SOURCE); //Create a reader PdfReader reader = new PdfReader(SOURCE); // step 1 Document document = new Document(PageSize.A5.rotate()); // step 2 PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(RESULT)); // step 3 document.open(); // step 4 PdfContentByte canvas = writer.getDirectContent(); PdfImportedPage page; BaseFont bf = BaseFont.createFont(BaseFont.ZAPFDINGBATS, "", BaseFont.EMBEDDED); for (int i = 0; i < reader.getNumberOfPages(); ) { page = writer.getImportedPage(reader, + + i); canvas.addTemplate(page, 1f, 0, 0.4f, 0.4f, 72, 50 * i); canvas.beginText(); canvas.setFontAndSize(bf, 20); canvas.showTextAligned(Element.ALIGN_CENTER, String.valueOf((char)(181 + i)), 496, 150 + 50 * i, 0); canvas.endText(); } // step 5 document.close(); } /** * Creates a PDF document. * @param filename the path to the new PDF document * @throws DocumentException * @throwsIOException */ public void createPdf(String filename) throws IOException, DocumentException { // step 1 Document document = new Document(PageSize.POSTCARD, 30, 30, 30, 30); // step 2 PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(filename)); // step 3 document.open(); // step 4 PdfContentByte under = writer.getDirectContentUnder(); // Page 1: a rectangle drawRectangle(under, PageSize.POSTCARD.getWidth(), PageSize.POSTCARD.getHeight()); under.setRGBColorFill(0xFF, 0xD7, 0x00); under.rectangle(5, 5, PageSize.POSTCARD.getWidth() - 10, PageSize.POSTCARD.getHeight() - 10); under.fill(); document.newPage(); // Page 2: an image drawRectangle(under, PageSize.POSTCARD.getWidth(), PageSize.POSTCARD.getHeight()); Image img = Image.getInstance(RESOURCE); img.setAbsolutePosition((PageSize.POSTCARD.getWidth() - img.getScaledWidth()) / 2, (PageSize.POSTCARD.getHeight() - img.getScaledHeight()) / 2); document.add(img); document.newPage(); // Page 3: the words "Foobar Film Festival" drawRectangle(under, PageSize.POSTCARD.getWidth(), PageSize.POSTCARD.getHeight());; Paragraph p = new Paragraph("Foobar Film Festival", new Font(FontFamily.HELVETICA, 22)); p.setAlignment(Element.ALIGN_CENTER); document.add(p); document.newPage(); // Page 4: the words "SOLD OUT" drawRectangle(under, PageSize.POSTCARD.getWidth(), PageSize.POSTCARD.getHeight()); PdfContentByte over = writer.getDirectContent(); over.saveState(); float sinus = (float)Math.sin(Math.PI / 60); float cosinus = (float)Math.cos(Math.PI / 60); BaseFont bf = BaseFont.createFont(); over.beginText(); over.setTextRenderingMode(PdfContentByte.TEXT_RENDER_MODE_FILL_STROKE); over.setLineWidth(1.5f); over.setRGBColorStroke(0xFF, 0x00, 0x00); over.setRGBColorFill(0xFF, 0xFF, 0xFF); over.setFontAndSize(bf, 36); over.setTextMatrix(cosinus, sinus, -sinus, cosinus, 50, 324); over.showText("SOLD OUT"); over.setTextMatrix(0, 0); over.endText(); over.restoreState(); // step 5 document.close(); } /** * Draws a rectangle * @param content the direct content layer * @param width the width of the rectangle * @param height the height of the rectangle */ public static void drawRectangle(PdfContentByte content, float width, float height) { content.saveState(); PdfGState state = new PdfGState(); state.setFillOpacity(0.6f); content.setGState(state); content.setRGBColorFill(0xFF, 0xFF, 0xFF); content.setLineWidth(3); content.rectangle(0, 0, width, height); content.fillStroke(); content.restoreState(); } }
Import company envelopes
Copy page from page N
6.3 Add content using PdfStamper
Add content at absolute position
PdfStamper.getOverContent() similar to getDirectContent()
import java.io.FileOutputStream; import java.io.IOException; import com.itextpdf.text.DocumentException; import com.itextpdf.text.Element; import com.itextpdf.text.Phrase; import com.itextpdf.text.pdf.ColumnText; import com.itextpdf.text.pdf.PdfContentByte; import com.itextpdf.text.pdf.PdfReader; import com.itextpdf.text.pdf.PdfStamper; import com.ygsoft.abc.component.cdes.itext.chapter1.HelloWorldLandscape1; import com.ygsoft.abc.component.cdes.itext.chapter1.HelloWorldLandscape2; public class StampText { /** A resulting PDF file. */ public static final String RESULT1 = "D:/data/iText/inAction/chapter06/hello1.pdf"; /** A resulting PDF file. */ public static final String RESULT2 = "D:/data/iText/inAction/chapter06/hello2.pdf"; /** A resulting PDF file. */ public static final String RESULT3 = "D:/data/iText/inAction/chapter06/hello3.pdf"; /** * Main method. * @param args no arguments needed * @throws DocumentException * @throwsIOException */ public static void main(String[] args) throws DocumentException, IOException { HelloWorldLandscape1.main(args); HelloWorldLandscape2.main(args); stamp(HelloWorldLandscape1.RESULT, RESULT1); stampIgnoreRotation(HelloWorldLandscape1.RESULT, RESULT2); stamp(HelloWorldLandscape2.RESULT, RESULT3); } /** * Manipulates a PDF file src with the file dest as result * @param src the original PDF * @param dest the resulting PDF * @throwsIOException * @throws DocumentException */ public static void stamp(String src, String dest) throws IOException, DocumentException { PdfReader reader = new PdfReader(src); PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest)); PdfContentByte canvas = stamper.getOverContent(1); ColumnText.showTextAligned(canvas, Element.ALIGN_LEFT, new Phrase("Hello people!"), 36, 540, 0); stamper.close(); } /** * Manipulates a PDF file src with the file dest as result * @param src the original PDF * @param dest the resulting PDF * @throwsIOException * @throws DocumentException */ public static void stampIgnoreRotation(String src, String dest) throws IOException, DocumentException { PdfReader reader = new PdfReader(src); PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest)); stamper.setRotateContents(false); PdfContentByte canvas = stamper.getOverContent(1); ColumnText.showTextAligned(canvas, Element.ALIGN_LEFT, new Phrase("Hello people!"), 36, 540, 0); stamper.close(); } }
Create PDF in 2 steps
The first step is to create the document content. The second step is to add page numbers.
import java.io.ByteArrayOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.sql.SQLException; import com.itextpdf.text.Document; import com.itextpdf.text.DocumentException; import com.itextpdf.text.Element; import com.itextpdf.text.PageSize; import com.itextpdf.text.Rectangle; import com.itextpdf.text.pdf.PdfPTable; import com.itextpdf.text.pdf.PdfReader; import com.itextpdf.text.pdf.PdfStamper; import com.itextpdf.text.pdf.PdfWriter; public class TwoPasses { /** The resulting PDF file. */ public static final String RESULT = "results/part2/chapter06/page_x_of_y.pdf"; /** * Main method. * @param args no arguments needed * @throws DocumentException * @throwsIOException * @throws SQLException * @throws SQLException */ public static void main(String[] args) throws SQLException, DocumentException, IOException { \t // FIRST PASS, CREATE THE PDF WITHOUT HEADER \t // step 1 Document document = new Document(PageSize.A4, 36, 36, 54, 36); // step 2 ByteArrayOutputStream baos = new ByteArrayOutputStream(); PdfWriter.getInstance(document, baos); // step 3 document.open(); // step 4 // PDF document creation... // step 5 document.close(); // SECOND PASS, ADD THE HEADER //Create a reader PdfReader reader = new PdfReader(baos.toByteArray()); //Create a stamper PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(RESULT)); // Loop over the pages and add a header to each page int n = reader.getNumberOfPages(); for (int i = 1; i <= n; i + + ) { getHeaderTable(i, n).writeSelectedRows( 0, -1, 34, 803, stamper.getOverContent(i)); } // Close the stamper stamper.close(); } /** * Create a header table with page X of Y * @param x the page number * @param y the total number of pages * @return a table that can be used as header */ public static PdfPTable getHeaderTable(int x, int y) { PdfPTable table = new PdfPTable(2); table.setTotalWidth(527); table.setLockedWidth(true); table.getDefaultCell().setFixedHeight(20); table.getDefaultCell().setBorder(Rectangle.BOTTOM); table.addCell("FOOBAR FILMFESTIVAL"); table.getDefaultCell().setHorizontalAlignment(Element.ALIGN_RIGHT); table.addCell(String.format("Page %d of %d", x, y)); return table; } }
Add a company envelope to an existing document
/** * Manipulates a PDF file src with the file dest as result * @param src the original PDF * @param stationery a PDF that will be added as background * @param dest the resulting PDF * @throwsIOException * @throws DocumentException */ public void manipulatePdf(String src, String stationery, String dest) throws IOException, DocumentException { // Create readers PdfReader reader = new PdfReader(src); PdfReader s_reader = new PdfReader(stationery); // Create the stamper PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest)); //Add the stationery to each page PdfImportedPage page = stamper.getImportedPage(s_reader, 1); int n = reader.getNumberOfPages(); PdfContentByte background; for (int i = 1; i <= n; i + + ) { background = stamper.getUnderContent(i); background.addTemplate(page, 0, 0); } // CLose the stamper stamper.close(); }
Insert pages into an existing document
Fill PDF form
6.4 Use PdfCopy to copy pages
Join and split PDF documents
Splice documents
import java.io.FileOutputStream; import java.io.IOException; import java.sql.SQLException; import com.itextpdf.text.Document; import com.itextpdf.text.DocumentException; import com.itextpdf.text.Element; import com.itextpdf.text.Phrase; import com.itextpdf.text.pdf.ColumnText; import com.itextpdf.text.pdf.PdfCopy; import com.itextpdf.text.pdf.PdfImportedPage; import com.itextpdf.text.pdf.PdfReader; public class ConcatenateStamp { /** The resulting PDF file. */ public static final String RESULT = "results/part2/chapter06/concatenated_stamped.pdf"; /** * Main method. * @param args no arguments needed * @throws DocumentException * @throwsIOException * @throws SQLException */ public static void main(String[] args) throws IOException, DocumentException, SQLException { // use old examples to create PDFs MovieLinks1.main(args); MovieHistory.main(args); // step 1 Document document = new Document(); // step 2 PdfCopy copy = new PdfCopy(document, new FileOutputStream(RESULT)); // step 3 document.open(); // step 4 // reader for document 1 PdfReader reader1 = new PdfReader(MovieLinks1.RESULT); int n1 = reader1.getNumberOfPages(); // reader for document 2 PdfReader reader2 = new PdfReader(MovieHistory.RESULT); int n2 = reader2.getNumberOfPages(); // initializations PdfImportedPage page; PdfCopy.PageStamp stamp; // Loop over the pages of document 1 for (int i = 0; i < n1; ) { page = copy.getImportedPage(reader1, + + i); stamp = copy.createPageStamp(page); // add page numbers ColumnText.showTextAligned( stamp.getUnderContent(), Element.ALIGN_CENTER, new Phrase(String.format("page %d of %d", i, n1 + n2)), 297.5f, 28, 0); stamp.alterContents(); copy.addPage(page); } // Loop over the pages of document 2 for (int i = 0; i < n2; ) { page = copy.getImportedPage(reader2, + + i); stamp = copy.createPageStamp(page); // add page numbers ColumnText.showTextAligned( stamp.getUnderContent(), Element.ALIGN_CENTER, new Phrase(String.format("page %d of %d", n1 + i, n1 + n2)), 297.5f, 28, 0); stamp.alterContents(); copy.addPage(page); } // step 5 document.close(); } }
Split document
import java.io.FileOutputStream; import java.io.IOException; import com.itextpdf.text.Document; import com.itextpdf.text.DocumentException; import com.itextpdf.text.pdf.PdfCopy; import com.itextpdf.text.pdf.PdfReader; public class Burst { /** Format of the resulting PDF files. */ public static final String RESULT = "D:/data/iText/inAction/chapter06/timetable_p%d.pdf"; /** * Main method. * @param args no arguments needed * @throws DocumentException * @throwsIOException */ public static void main(String[] args) throws IOException, DocumentException { //Create a reader PdfReader reader = new PdfReader("D:/data/iText/inAction/chapter03/movie_posters.pdf"); // We'll create as many new PDFs as there are pages Document document; PdfCopy copy; // loop over all the pages in the original PDF int n = reader.getNumberOfPages(); for (int i = 0; i < n; ) { // step 1 document = new Document(); // step 2 copy = new PdfCopy(document, new FileOutputStream(String.format(RESULT, + + i))); // step 3 document.open(); // step 4 copy.addPage(copy.getImportedPage(reader, i)); // step 5 document.close(); } } }
PdfCopy VS PdfSmartCopy
PdfSmartCopy
Inherited from PdfCopy, it checks for redundant objects added on each page.
thus saving a lot of disk space or
bandwidth. This extra “wisdom” comes at a cost. PdfSmartCopy requires more memory and time to stitch documents together.
Prioritize file size and bandwidth, select PdfSmartCopy
Prioritize memory and time, select PdfCopy
Splice form