Chapter 6: Working with existing PDFs

10th October 2015
admin-marketing

These examples were written in the context of Chapter 6 of the book "iText in Action - Second Edition".

PageInformation.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part2.chapter06;
 
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;
 
import part1.chapter01.HelloWorldLandscape1;
import part1.chapter01.HelloWorldLandscape2;
import part1.chapter03.MovieTemplates;
import part1.chapter05.Hero1;
 
public class PageInformation {
 
    /** The resulting text file with info about a PDF. */
    public static final String RESULT
        = "results/part2/chapter06/page_info.txt";
    
    /**
     * Main method.
     * @param args no arguments needed
     * @throws DocumentException 
     * @throws IOException
     */
    public static void main(String[] args)
        throws DocumentException, IOException {
        // Use old examples to create PDFs
        HelloWorldLandscape1.main(args);
        HelloWorldLandscape2.main(args);
        MovieTemplates.main(args);
        Hero1.main(args);
        // Inspecting PDFs
        PrintWriter writer = new PrintWriter(new FileOutputStream(RESULT));
        inspect(writer, HelloWorldLandscape1.RESULT);
        inspect(writer, HelloWorldLandscape2.RESULT);
        inspect(writer, MovieTemplates.RESULT);
        inspect(writer, Hero1.RESULT);
        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
     * @throws IOException
     */
    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();
        reader.close();
    }
}
MemoryInfo.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part2.chapter06;
 
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.RandomAccessFileOrArray;
import part1.chapter03.MovieTemplates;
 
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
 
public class MemoryInfo {
 
    /** The resulting PDF file. */
    public static final String RESULT
        = "results/part2/chapter06/memory_info.txt";
    
    /**
     * Main method.
     * @param args no arguments needed
     * @throws DocumentException 
     * @throws IOException
     */
    public static void main(String[] args)
        throws IOException, DocumentException {
        // Use a previous example to create a PDF
        MovieTemplates.main(args);
        // Create a writer for a report file
        PrintWriter writer
            = new PrintWriter(new FileOutputStream(RESULT));
        garbageCollect();
        // Do a full read
        fullRead(writer, MovieTemplates.RESULT);
        // Do a partial read
        partialRead(writer, MovieTemplates.RESULT);
        // Close the text file writer
        writer.close();
    }
    
    /**
     * Do a full read of a PDF file
     * @param writer a writer to a report file
     * @param filename the file to read
     * @throws IOException
     */
    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();
        reader.close();
    }
    
    /**
     * Do a partial read of a PDF file
     * @param writer a writer to a report file
     * @param filename the file to read
     * @throws IOException
     */
    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();
        reader.close();
    }
 
    /**
     * Returns the current memory use.
     * 
     * @return the current memory use
     */
    public static long getMemoryUse() {
        garbageCollect();
        garbageCollect();
        garbageCollect();
        garbageCollect();
        long totalMemory = Runtime.getRuntime().totalMemory();
        garbageCollect();
        garbageCollect();
        long freeMemory = Runtime.getRuntime().freeMemory();
        return (totalMemory - freeMemory);
    }
 
    /**
     * Makes sure all garbage is cleared from the memory.
     */
    public static void garbageCollect() {
        try {
            System.gc();
            Thread.sleep(200);
            System.runFinalization();
            Thread.sleep(200);
            System.gc();
            Thread.sleep(200);
            System.runFinalization();
            Thread.sleep(200);
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }
    }
}
SelectPages.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part2.chapter06;
 
import java.io.FileOutputStream;
import java.io.IOException;
 
import part1.chapter03.MovieTemplates;
 
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 
     * @throws IOException
     */
    public static void main(String[] args) throws IOException, DocumentException {
        new MovieTemplates().createPdf(MovieTemplates.RESULT);
        PdfReader reader = new PdfReader(MovieTemplates.RESULT);
        reader.selectPages("4-8");
        manipulateWithStamper(reader);
        manipulateWithCopy(reader);
        reader.close();
    }
 
    /**
     * Creates a new PDF based on the one in the reader
     * @param reader a reader with a PDF file
     * @throws IOException
     * @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
     * @throws IOException
     * @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();
    }
    
    
}
ImportingPages1.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part2.chapter06;
 
import java.io.FileOutputStream;
import java.io.IOException;
 
import part1.chapter03.MovieTemplates;
 
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
        = "results/part2/chapter06/time_table_imported1.pdf";
    
    /**
     * Main method.
     * @param args no arguments needed
     * @throws DocumentException 
     * @throws IOException
     */
    public static void main(String[] args)
        throws IOException, DocumentException {
        // Use old example to create PDF
        new MovieTemplates().createPdf(MovieTemplates.RESULT);
        // 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(MovieTemplates.RESULT);
        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();
        reader.close();
    }
}
ImportingPages2.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part2.chapter06;
 
import java.io.FileOutputStream;
import java.io.IOException;
 
import part1.chapter03.MovieTemplates;
 
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 ImportingPages2 {
 
    /** The resulting PDF file. */
    public static final String RESULT
        = "results/part2/chapter06/time_table_imported2.pdf";
    
    /**
     * Main method.
     * @param args no arguments needed
     * @throws DocumentException 
     * @throws IOException
     */
    public static void main(String[] args)
        throws IOException, DocumentException {
        // use old example to create PDF
        new MovieTemplates().createPdf(MovieTemplates.RESULT);
        // step 1
        Document document = new Document();
        // step 2
        PdfWriter writer
            = PdfWriter.getInstance(document, new FileOutputStream(RESULT));
        // step 3
        document.open();
        // step 4
        PdfReader reader = new PdfReader(MovieTemplates.RESULT);
        int n = reader.getNumberOfPages();
        PdfImportedPage page;
        PdfPTable table = new PdfPTable(2);
        for (int i = 1; i <= n; i++) {
            page = writer.getImportedPage(reader, i);
            table.getDefaultCell().setRotation(-page.getRotation());
            table.addCell(Image.getInstance(page));
        }
        document.add(table);
        // step 5
        document.close();
        reader.close();
    }
}
Layers.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part2.chapter06;
 
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
        = "results/part2/chapter06/layers_orig.pdf";
    /** The resulting PDF. */
    public static final String RESULT
        = "results/part2/chapter06/layers.pdf";
    /** The movie poster. */
    public static final String RESOURCE
        = "resources/img/loa.jpg";
    
    /**
     * Main method.
     * @param args no arguments needed
     * @throws DocumentException 
     * @throws IOException
     */
    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();
        reader.close();
    }
 
    /**
     * Creates a PDF document.
     * @param filename the path to the new PDF document
     * @throws    DocumentException 
     * @throws    IOException
     */
    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();
    }
}
Superimposing.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part2.chapter06;
 
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.PdfImportedPage;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfWriter;
 
public class Superimposing {
 
    /** The resulting PDF. */
    public static final String SOURCE
        = "results/part2/chapter06/opening.pdf";
    /** The resulting PDF. */
    public static final String RESULT
        = "results/part2/chapter06/festival_opening.pdf";
    /** The movie poster. */
    public static final String RESOURCE
        = "resources/img/loa.jpg";
 
    /**
     * Main method.
     * @param    args    no arguments needed
     * @throws DocumentException 
     * @throws IOException
     */
    public static void main(String[] args)
        throws IOException, DocumentException {
        new Superimposing().createPdf(SOURCE);
        // Create a reader object
        PdfReader reader = new PdfReader(SOURCE);
        // step 1
        Document document = new Document(PageSize.POSTCARD);
        // step 2
        PdfWriter writer
            = PdfWriter.getInstance(document, new FileOutputStream(RESULT));
        // step 3
        document.open();
        // step 4
        PdfContentByte canvas = writer.getDirectContent();
        PdfImportedPage page;
        for (int i = 1; i <= reader.getNumberOfPages(); i++) {
            page = writer.getImportedPage(reader, i);
            canvas.addTemplate(page, 1f, 0, 0, 1, 0, 0);
        }
        // step 5
        document.close();
        reader.close();
    }
 
    /**
     * Creates a PDF document.
     * @param filename the path to the new PDF document
     * @throws    DocumentException 
     * @throws    IOException
     */
    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: rectangle
        under.setRGBColorFill(0xFF, 0xD7, 0x00);
        under.rectangle(5, 5,
            PageSize.POSTCARD.getWidth() - 10, PageSize.POSTCARD.getHeight() - 10);
        under.fill();
        document.newPage();
        // page 2: image
        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"
        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"
        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();
    }
}
Stationery.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part2.chapter06;
 
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Set;
import java.util.TreeSet;
 
import com.lowagie.database.DatabaseConnection;
import com.lowagie.database.HsqldbConnection;
import com.lowagie.filmfestival.FilmFonts;
import com.lowagie.filmfestival.Movie;
import com.lowagie.filmfestival.MovieComparator;
import com.lowagie.filmfestival.PojoFactory;
import com.lowagie.filmfestival.PojoToElementFactory;
import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.Font.FontFamily;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.GrayColor;
import com.itextpdf.text.pdf.PdfImportedPage;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfPageEventHelper;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfWriter;
 
public class Stationery extends PdfPageEventHelper {
 
    /** The original PDF. */
    public static final String STATIONERY
        = "results/part2/chapter06/stationery.pdf";
    /** The resulting PDF. */
    public static final String RESULT
        = "results/part2/chapter06/text_on_stationery.pdf";
    
    /**
     * Main method.
     * @param args no arguments needed
     * @throws DocumentException 
     * @throws IOException
     * @throws SQLException
     */
    public static void main(String[] args)
        throws IOException, DocumentException, SQLException {
        Stationery stationary = new Stationery();
        createStationary(STATIONERY);
        stationary.createPdf(RESULT);
    }
 
    /**
     * Creates a PDF document.
     * @param filename the path to the new PDF document
     * @throws    DocumentException 
     * @throws    IOException
     * @throws    SQLException
     */
    public void createPdf(String filename)
        throws SQLException, IOException, DocumentException {
        // Create the database connection
        DatabaseConnection connection = new HsqldbConnection("filmfestival");
        // step 1
        Document document = new Document(PageSize.A4, 36, 36, 72, 36);
        // step 2
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(filename));
        useStationary(writer);
        // step 3
        document.open();
        // step 4
        Statement stm = connection.createStatement();
        ResultSet rs = stm.executeQuery(
            "SELECT country, id FROM film_country ORDER BY country");
        while (rs.next()) {
            document.add(new Paragraph(rs.getString("country"), FilmFonts.BOLD));
            document.add(Chunk.NEWLINE);
            Set<Movie> movies = 
                new TreeSet<Movie>(new MovieComparator(MovieComparator.BY_YEAR));
            movies.addAll(PojoFactory.getMovies(connection, rs.getString("id")));
            for(Movie movie : movies) {
                document.add(new Paragraph(movie.getMovieTitle(), FilmFonts.BOLD));
                if (movie.getOriginalTitle() != null)
                    document.add(new Paragraph(movie.getOriginalTitle(), FilmFonts.ITALIC));
                document.add(new Paragraph(
                    String.format("Year: %d; run length: %d minutes",
                    movie.getYear(), movie.getDuration()), FilmFonts.NORMAL));
                document.add(PojoToElementFactory.getDirectorList(movie));
            }
            document.newPage();
        }
        // step 5
        document.close();
        // Close the database connection
        connection.close();
    }
    
    /** Imported page with the stationery. */
    protected PdfImportedPage page;
 
    /**
     * Initialize the imported page.
     * @param writer The PdfWriter
     * @throws IOException
     */
    public void useStationary(PdfWriter writer) throws IOException {
        writer.setPageEvent(this);
        PdfReader reader = new PdfReader(STATIONERY);
        page = writer.getImportedPage(reader, 1);
    }
    
    /**
     * @see com.itextpdf.text.pdf.PdfPageEventHelper#onEndPage(
     *      com.itextpdf.text.pdf.PdfWriter, com.itextpdf.text.Document)
     */
    public void onEndPage(PdfWriter writer, Document document) {
        writer.getDirectContentUnder().addTemplate(page, 0, 0);
    }
 
    /**
     * Creates a PDF document.
     * @param filename the path to the new PDF document
     * @throws    DocumentException 
     * @throws    IOException
     * @throws    SQLException
     */
    public static void createStationary(String filename)
        throws IOException, DocumentException {
        // step 1
        Document document = new Document();
        // step 2
        PdfWriter writer
            = PdfWriter.getInstance(document, new FileOutputStream(filename));
        // step 3
        document.open();
        // step 4
        PdfPTable table = new PdfPTable(1);
        table.getDefaultCell().setHorizontalAlignment(Element.ALIGN_CENTER);
        table.addCell(new Phrase("FOOBAR FILM FESTIVAL", FilmFonts.BOLD));
        document.add(table);
        Font font = new Font(FontFamily.HELVETICA, 52, Font.BOLD, new GrayColor(0.75f));
        ColumnText.showTextAligned(writer.getDirectContentUnder(),
                Element.ALIGN_CENTER, new Phrase("FOOBAR FILM FESTIVAL", font),
                297.5f, 421, 45);
        // step 5
        document.close();
    }
}
NUpTool.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part2.chapter06;
 
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.Rectangle;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfImportedPage;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfWriter;
 
public class NUpTool {
 
    /** Format of the resulting PDF files. */
    public static final String RESULT
        = "results/part2/chapter06/result%dup.pdf";
    
    /**
     * Manipulates a PDF file src with the file dest as result
     * @param src the original PDF
     * @param dest the resulting PDF
     * @param pow the PDF will be N-upped with N = Math.pow(2, pow);
     * @throws IOException
     * @throws DocumentException
     * @throws SQLException
     */
    public void manipulatePdf(String src, String dest, int pow)
        throws IOException, DocumentException {
        // reader for the src file
        PdfReader reader = new PdfReader(src);
        // initializations
        Rectangle pageSize = reader.getPageSize(1);
        Rectangle newSize = (pow % 2) == 0 ?
            new Rectangle(pageSize.getWidth(), pageSize.getHeight()) :
            new Rectangle(pageSize.getHeight(), pageSize.getWidth());
        Rectangle unitSize = new Rectangle(pageSize.getWidth(), pageSize.getHeight());
        for (int i = 0; i < pow; i++) {
            unitSize = new Rectangle(unitSize.getHeight() / 2, unitSize.getWidth());
        }
        int n = (int)Math.pow(2, pow);
        int r = (int)Math.pow(2, pow / 2);
        int c = n / r;
        // step 1
        Document document = new Document(newSize, 0, 0, 0, 0);
        // step 2
        PdfWriter writer
           = PdfWriter.getInstance(document, new FileOutputStream(String.format(dest, n)));
        // step 3
        document.open();
        // step 4
        PdfContentByte cb = writer.getDirectContent();
        PdfImportedPage page;
        Rectangle currentSize;
        float offsetX, offsetY, factor;
        int total = reader.getNumberOfPages();
        for (int i = 0; i < total; ) {
            if (i % n == 0) {
                document.newPage();
            }
            currentSize = reader.getPageSize(++i);
            factor = Math.min(
                unitSize.getWidth() / currentSize.getWidth(),
                unitSize.getHeight() / currentSize.getHeight());
            offsetX = unitSize.getWidth() * ((i % n) % c)
              + (unitSize.getWidth() - (currentSize.getWidth() * factor)) / 2f;
            offsetY = newSize.getHeight() - (unitSize.getHeight() * (((i % n) / c) + 1))
              + (unitSize.getHeight() - (currentSize.getHeight() * factor)) / 2f;
            page = writer.getImportedPage(reader, i);
            cb.addTemplate(page, factor, 0, 0, factor, offsetX, offsetY);
        }
        // step 5
        document.close();
        reader.close();
    }
    
    /**
     * Main method.
     * @param args no arguments needed
     * @throws DocumentException 
     * @throws IOException
     * @throws SQLException
     */
    public static void main(String[] args)
        throws IOException, DocumentException, SQLException {
        Stationery.main(args);
        new NUpTool().manipulatePdf(Stationery.RESULT, RESULT, 1);
        new NUpTool().manipulatePdf(Stationery.RESULT, RESULT, 2);
        new NUpTool().manipulatePdf(Stationery.RESULT, RESULT, 3);
        new NUpTool().manipulatePdf(Stationery.RESULT, RESULT, 4);
    }
}
TilingHero.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part2.chapter06;
 
import java.io.FileOutputStream;
import java.io.IOException;
 
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfImportedPage;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfWriter;
 
public class TilingHero {
 
    /** The original PDF file. */
    public static final String RESOURCE
        = "resources/pdfs/hero.pdf";
 
    /** The resulting PDF file. */
    public static final String RESULT
        = "results/part2/chapter06/superman.pdf";
    
    /**
     * Manipulates a PDF file src with the file dest as result
     * @param src the original PDF
     * @param dest the resulting PDF
     * @throws IOException
     * @throws DocumentException
     */
    public void manipulatePdf(String src, String dest)
        throws IOException, DocumentException {
        // Creating a reader
        PdfReader reader = new PdfReader(src);
        Rectangle pagesize = reader.getPageSizeWithRotation(1);
        // step 1
        Document document = new Document(pagesize);
        // step 2
        PdfWriter writer
            = PdfWriter.getInstance(document, new FileOutputStream(dest));
        // step 3
        document.open();
        // step 4
        PdfContentByte content = writer.getDirectContent();
        PdfImportedPage page = writer.getImportedPage(reader, 1);
        // adding the same page 16 times with a different offset
        float x, y;
        for (int i = 0; i < 16; i++) {
            x = -pagesize.getWidth() * (i % 4);
            y = pagesize.getHeight() * (i / 4 - 3);
            content.addTemplate(page, 4, 0, 0, 4, x, y);
            document.newPage();
        }
        // step 4
        document.close();
        reader.close();
    }
 
    /**
     * Main method.
     * @param    args    no arguments needed
     * @throws DocumentException 
     * @throws IOException
     */
    public static void main(String[] args)
        throws IOException, DocumentException {
        new TilingHero().manipulatePdf(RESOURCE, RESULT);
    }
}
StampText.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part2.chapter06;
 
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 part1.chapter01.HelloWorldLandscape1;
import part1.chapter01.HelloWorldLandscape2;
 
public class StampText {
    /** A resulting PDF file. */
    public static final String RESULT1
        = "results/part2/chapter06/hello1.pdf";
    /** A resulting PDF file. */
    public static final String RESULT2
        = "results/part2/chapter06/hello2.pdf";
    /** A resulting PDF file. */
    public static final String RESULT3
        = "results/part2/chapter06/hello3.pdf";
    
    /**
     * Main method.
     * @param args no arguments needed
     * @throws DocumentException 
     * @throws IOException
     */
    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
     * @throws IOException
     * @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();
        reader.close();
    }
 
    /**
     * Manipulates a PDF file src with the file dest as result
     * @param src the original PDF
     * @param dest the resulting PDF
     * @throws IOException
     * @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();
        reader.close();
    }
}
TwoPasses.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part2.chapter06;
 
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Set;
import java.util.TreeSet;
 
import com.lowagie.database.DatabaseConnection;
import com.lowagie.database.HsqldbConnection;
import com.lowagie.filmfestival.FilmFonts;
import com.lowagie.filmfestival.Movie;
import com.lowagie.filmfestival.MovieComparator;
import com.lowagie.filmfestival.PojoFactory;
import com.lowagie.filmfestival.PojoToElementFactory;
import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
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 
     * @throws IOException 
     * @throws SQLException
     * @throws SQLException
     */
    public static void main(String[] args)
        throws SQLException, DocumentException, IOException {
        
        // FIRST PASS, CREATE THE PDF WITHOUT HEADER
        
        // Create a database connection
        DatabaseConnection connection = new HsqldbConnection("filmfestival");
        // 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
        Statement stm = connection.createStatement();
        ResultSet rs = stm.executeQuery(
            "SELECT country, id FROM film_country ORDER BY country");
        while (rs.next()) {
            document.add(new Paragraph(rs.getString("country"), FilmFonts.BOLD));
            document.add(Chunk.NEWLINE);
            Set<Movie> movies = 
                new TreeSet<Movie>(new MovieComparator(MovieComparator.BY_YEAR));
            movies.addAll(PojoFactory.getMovies(connection, rs.getString("id")));
            for(Movie movie : movies) {
                document.add(new Paragraph(movie.getMovieTitle(), FilmFonts.BOLD));
                if (movie.getOriginalTitle() != null)
                    document.add(
                        new Paragraph(movie.getOriginalTitle(), FilmFonts.ITALIC));
                document.add(new Paragraph(
                    String.format("Year: %d; run length: %d minutes",
                    movie.getYear(), movie.getDuration()), FilmFonts.NORMAL));
                document.add(PojoToElementFactory.getDirectorList(movie));
            }
            document.newPage();
        }
        // step 5
        document.close();
        // Close the database connection
        connection.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();
        reader.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;
    }
}
StampStationery.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part2.chapter06;
 
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Set;
import java.util.TreeSet;
 
import com.lowagie.database.DatabaseConnection;
import com.lowagie.database.HsqldbConnection;
import com.lowagie.filmfestival.FilmFonts;
import com.lowagie.filmfestival.Movie;
import com.lowagie.filmfestival.MovieComparator;
import com.lowagie.filmfestival.PojoFactory;
import com.lowagie.filmfestival.PojoToElementFactory;
import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfImportedPage;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.PdfWriter;
 
public class StampStationery {
    /** The original PDF file. */
    public static final String ORIGINAL
        = "results/part2/chapter06/original.pdf";
    /** The resulting PDF. */
    public static final String RESULT
        = "results/part2/chapter06/stamped_stationary.pdf";
    
    /**
     * Main method.
     * @param args no arguments needed
     * @throws DocumentException 
     * @throws IOException
     * @throws SQLException
     */
    public static void main(String[] args)
        throws IOException, DocumentException, SQLException {
        Stationery.createStationary(Stationery.STATIONERY);
        StampStationery stationary = new StampStationery();
        stationary.createPdf(ORIGINAL);
        stationary.manipulatePdf(ORIGINAL, Stationery.STATIONERY, RESULT);
    }
    
    /**
     * 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
     * @throws IOException
     * @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();
        reader.close();
        s_reader.close();
    }
 
    /**
     * Creates a PDF document.
     * @param filename the path to the new PDF document
     * @throws    DocumentException 
     * @throws    IOException
     * @throws    SQLException
     */
    public void createPdf(String filename)
        throws SQLException, IOException, DocumentException {
        // Create a database connection
        DatabaseConnection connection = new HsqldbConnection("filmfestival");
        // step 1
        Document document = new Document(PageSize.A4, 36, 36, 72, 36);
        // step 2
        PdfWriter.getInstance(document, new FileOutputStream(filename));
        // step 3
        document.open();
        // step 4
        Statement stm = connection.createStatement();
        ResultSet rs = stm.executeQuery(
            "SELECT country, id FROM film_country ORDER BY country");
        while (rs.next()) {
            document.add(new Paragraph(rs.getString("country"), FilmFonts.BOLD));
            document.add(Chunk.NEWLINE);
            Set<Movie> movies = 
                new TreeSet<Movie>(new MovieComparator(MovieComparator.BY_YEAR));
            movies.addAll(PojoFactory.getMovies(connection, rs.getString("id")));
            for(Movie movie : movies) {
                document.add(new Paragraph(movie.getMovieTitle(), FilmFonts.BOLD));
                if (movie.getOriginalTitle() != null)
                    document.add(new Paragraph(movie.getOriginalTitle(), FilmFonts.ITALIC));
                document.add(new Paragraph(
                    String.format("Year: %d; run length: %d minutes",
                    movie.getYear(), movie.getDuration()), FilmFonts.NORMAL));
                document.add(PojoToElementFactory.getDirectorList(movie));
            }
            document.newPage();
        }
        // step 5
        document.close();
        // Close the database connection
        connection.close();
    }
}
InsertPages.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part2.chapter06;
 
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
 
import com.lowagie.database.DatabaseConnection;
import com.lowagie.database.HsqldbConnection;
import com.itextpdf.text.Chunk;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.PdfImportedPage;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
 
public class InsertPages {
    /** A resulting PDF. */
    public static final String RESULT1
        = "results/part2/chapter06/inserted_pages.pdf";
    /** A resulting PDF. */
    public static final String RESULT2
        = "results/part2/chapter06/reordered.pdf";
    
    /**
     * Main method.
     * @param args no arguments needed
     * @throws DocumentException 
     * @throws IOException
     * @throws SQLException
     */
    public static void main(String[] args)
        throws IOException, DocumentException, SQLException {
        // use a previous example to create a PDF
        StampStationery.main(args);
        // manipulate the PDF
        new InsertPages().manipulatePdf(StampStationery.RESULT, RESULT1);
        // reorder the pages in the PDF
        PdfReader reader = new PdfReader(RESULT1);
        reader.selectPages("3-41,1-2");
        PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(RESULT2));
        stamper.close();
        reader.close();
    }
    
    /**
     * Manipulates a PDF file src with the file dest as result
     * @param src the original PDF
     * @param dest the resulting PDF
     * @throws IOException
     * @throws DocumentException
     * @throws SQLException
     */
    public void manipulatePdf(String src, String dest)
        throws IOException, DocumentException, SQLException {
        // Create a database connection and statement
        DatabaseConnection connection = new HsqldbConnection("filmfestival");
        Statement stm = connection.createStatement();
        // Fill a ColumnText object with data
        ResultSet rs = stm.executeQuery(
            "SELECT country, id FROM film_country ORDER BY country");
        ColumnText ct = new ColumnText(null);
        while (rs.next()) {
            ct.addElement(new Paragraph(24, new Chunk(rs.getString("country"))));
        }
        // Close the statement and database connection
        stm.close();
        connection.close();
        
        // Create a reader for the original document and for the stationery
        PdfReader reader = new PdfReader(src);
        PdfReader stationery = new PdfReader(Stationery.STATIONERY);
        // Create a stamper
        PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
        // Create an imported page for the stationery
        PdfImportedPage page = stamper.getImportedPage(stationery, 1);
        int i = 0;
        // Add the content of the ColumnText object 
        while(true) {
            // Add a new page
            stamper.insertPage(++i, reader.getPageSize(1));
            // Add the stationary to the new page
            stamper.getUnderContent(i).addTemplate(page, 0, 0);
            // Add as much content of the column as possible
            ct.setCanvas(stamper.getOverContent(i));
            ct.setSimpleColumn(36, 36, 559, 770);
            if (!ColumnText.hasMoreText(ct.go()))
                break;
        }
        // Close the stamper
        stamper.close();
        reader.close();
        stationery.close();
    }
}
FormInformation.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part2.chapter06;
 
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Set;
 
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.PdfReader;
 
public class FormInformation {
 
    /** The original PDF file. */
    public static final String DATASHEET
        = "resources/pdfs/datasheet.pdf";
    /** The resulting text file with the field info. */
    public static final String RESULT
        = "results/part2/chapter06/form_info.txt";    
    
    /**
     * Main method.
     * @param args no arguments needed
     * @throws DocumentException 
     * @throws IOException
     */
    public static void main(String[] args)
        throws DocumentException, IOException {
        // Create a writer for the report file
        PrintWriter writer
            = new PrintWriter(new FileOutputStream(RESULT));
        // Create a reader to extract info
        PdfReader reader = new PdfReader(DATASHEET);
        // Get the fields from the reader (read-only!!!)
        AcroFields form = reader.getAcroFields();
        // Loop over the fields and get info about them
        Set<String> fields = form.getFields().keySet();
        for (String key : fields) {
            writer.print(key + ": ");
            switch (form.getFieldType(key)) {
            case AcroFields.FIELD_TYPE_CHECKBOX:
                writer.println("Checkbox");
                break;
            case AcroFields.FIELD_TYPE_COMBO:
                writer.println("Combobox");
                break;
            case AcroFields.FIELD_TYPE_LIST:
                writer.println("List");
                break;
            case AcroFields.FIELD_TYPE_NONE:
                writer.println("None");
                break;
            case AcroFields.FIELD_TYPE_PUSHBUTTON:
                writer.println("Pushbutton");
                break;
            case AcroFields.FIELD_TYPE_RADIOBUTTON:
                writer.println("Radiobutton");
                break;
            case AcroFields.FIELD_TYPE_SIGNATURE:
                writer.println("Signature");
                break;
            case AcroFields.FIELD_TYPE_TEXT:
                writer.println("Text");
                break;
            default:
                writer.println("?");
            }
        }
        // Get possible values for field "CP_1"
        writer.println("Possible values for CP_1:");
        String[] states = form.getAppearanceStates("CP_1");
        for (int i = 0; i < states.length; i++) {
            writer.print(" - ");
            writer.println(states[i]);
        }
        // Get possible values for field "category"
        writer.println("Possible values for category:");
        states = form.getAppearanceStates("category");
        for (int i = 0; i < states.length - 1; i++) {
            writer.print(states[i]);
            writer.print(", ");
        }
        writer.println(states[states.length - 1]);
        // flush and close the report file
        writer.flush();
        writer.close();
        reader.close();
    }
 
}
FillDataSheet.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part2.chapter06;
 
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
 
import com.lowagie.database.DatabaseConnection;
import com.lowagie.database.HsqldbConnection;
import com.lowagie.filmfestival.Director;
import com.lowagie.filmfestival.Movie;
import com.lowagie.filmfestival.PojoFactory;
import com.lowagie.filmfestival.Screening;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
 
public class FillDataSheet {
 
    /** The original PDF file. */
    public static final String DATASHEET
        = "resources/pdfs/datasheet.pdf";
    /** The resulting PDF file. */
    public static final String RESULT
        = "results/part2/chapter06/imdb%s.pdf";
    
    /**
     * Main method.
     * @param args no arguments needed
     * @throws DocumentException 
     * @throws IOException
     * @throws SQLException
     */
    public static void main(String[] args)
        throws SQLException, IOException, DocumentException {
        // Create a database connection
        DatabaseConnection connection = new HsqldbConnection("filmfestival");
        // Get the movies
        List<Movie> movies = PojoFactory.getMovies(connection);
        PdfReader reader;
        PdfStamper stamper;
        // Fill out the data sheet form with data
        for (Movie movie : movies) {
            if (movie.getYear() < 2007)
                continue;
            reader = new PdfReader(DATASHEET);
            stamper = new PdfStamper(reader,
                    new FileOutputStream(String.format(RESULT, movie.getImdb())));
            AcroFields fields = stamper.getAcroFields();
            fields.setGenerateAppearances(true);
            fill(fields, movie);
            if (movie.getYear() == 2007)
                stamper.setFormFlattening(true);
            stamper.close();
            reader.close();
        }
        // Close the database connection
        connection.close();
    }
    
    /**
     * Fill out the fields using info from a Movie object.
     * @param form The form object
     * @param movie A movie POJO
     * @throws IOException
     * @throws DocumentException
     */
    public static void fill(AcroFields form, Movie movie)
        throws IOException, DocumentException {
        form.setField("title", movie.getMovieTitle());
        form.setField("director", getDirectors(movie));
        form.setField("year", String.valueOf(movie.getYear()));
        form.setField("duration", String.valueOf(movie.getDuration()));
        form.setField("category", movie.getEntry().getCategory().getKeyword());
        for (Screening screening : movie.getEntry().getScreenings()) {
            form.setField(screening.getLocation().replace('.', '_'), "Yes");
        }
    }
    
    /**
     * Gets the directors from a Movie object,
     * and concatenates them in a String.
     * @param movie a Movie object
     * @return a String containing director names
     */
    public static String getDirectors(Movie movie) {
        List<Director> directors = movie.getDirectors();
        StringBuffer buf = new StringBuffer();
        for (Director director : directors) {
            buf.append(director.getGivenName());
            buf.append(' ');
            buf.append(director.getName());
            buf.append(',');
            buf.append(' ');
        }
        int i = buf.length();
        if (i > 0)
            buf.delete(i - 2, i);
        return buf.toString();
    }
}
Concatenate.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part2.chapter06;
 
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.pdf.PdfCopy;
import com.itextpdf.text.pdf.PdfReader;
 
import part1.chapter02.MovieHistory;
import part1.chapter02.MovieLinks1;
 
public class Concatenate {
 
    /** The resulting PDF file. */
    public static final String RESULT
        = "results/part2/chapter06/concatenated.pdf";
 
    /**
     * Main method.
     * @param    args    no arguments needed
     * @throws DocumentException 
     * @throws IOException
     * @throws SQLException
     */
    public static void main(String[] args)
        throws IOException, DocumentException, SQLException {
        // using previous examples to create PDFs
        MovieLinks1.main(args);
        MovieHistory.main(args);
        String[] files = { MovieLinks1.RESULT, MovieHistory.RESULT };
        // step 1
        Document document = new Document();
        // step 2
        PdfCopy copy = new PdfCopy(document, new FileOutputStream(RESULT));
        // step 3
        document.open();
        // step 4
        PdfReader reader;
        int n;
        // loop over the documents you want to concatenate
        for (int i = 0; i < files.length; i++) {
            reader = new PdfReader(files[i]);
            // loop over the pages in that document
            n = reader.getNumberOfPages();
            for (int page = 0; page < n; ) {
                copy.addPage(copy.getImportedPage(reader, ++page));
            }
            copy.freeReader(reader);
            reader.close();
        }
        // step 5
        document.close();
    }
}
ConcatenateStamp.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part2.chapter06;
 
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;
 
import part1.chapter02.MovieHistory;
import part1.chapter02.MovieLinks1;
 
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 
     * @throws IOException
     * @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();
        reader1.close();
        reader2.close();
    }
}
Burst.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part2.chapter06;
 
import java.io.FileOutputStream;
import java.io.IOException;
 
import part1.chapter03.MovieTemplates;
 
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
        = "results/part2/chapter06/timetable_p%d.pdf";
 
    /**
     * Main method.
     * @param    args    no arguments needed
     * @throws DocumentException 
     * @throws IOException
     */
    public static void main(String[] args)
        throws IOException, DocumentException {
        // use one of the previous examples to create a PDF
        new MovieTemplates().createPdf(MovieTemplates.RESULT);
        // Create a reader
        PdfReader reader = new PdfReader(MovieTemplates.RESULT);
        // 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();
        }
        reader.close();
    }
    
    
}
DataSheets1.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part2.chapter06;
 
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
 
import com.lowagie.database.DatabaseConnection;
import com.lowagie.database.HsqldbConnection;
import com.lowagie.filmfestival.Movie;
import com.lowagie.filmfestival.PojoFactory;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.PdfCopy;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
 
public class DataSheets1 extends FillDataSheet {
 
    /** The resulting PDF file. */
    public static final String RESULT
        = "results/part2/chapter06/datasheets1.pdf";
    
    /**
     * Main method.
     * @param args no arguments needed
     * @throws DocumentException 
     * @throws IOException
     * @throws SQLException
     */
    public static void main(String[] args)
        throws IOException, SQLException, DocumentException {
        new DataSheets1().createPdf(RESULT);
    }
 
    /**
     * Creates a PDF document.
     * @param filename the path to the new PDF document
     * @throws    DocumentException 
     * @throws    IOException
     * @throws    SQLException
     */
    public void createPdf(String filename)
        throws IOException, DocumentException, SQLException {
        // step 1
        Document document = new Document();
        // step 2
        PdfCopy copy
            = new PdfCopy(document, new FileOutputStream(filename));
        // step 3
        document.open();
        // step 4
        addDataSheets(copy);
        // step 5
        document.close();
    }
    
    /**
     * Fills out a data sheet, flattens it, and adds it to a combined PDF.
     * @param copy the PdfCopy instance (can also be PdfSmartCopy)
     * @throws SQLException
     * @throws IOException
     * @throws DocumentException
     */
    public void addDataSheets(PdfCopy copy)
        throws SQLException, IOException, DocumentException {
        // Create a database connection
        DatabaseConnection connection = new HsqldbConnection("filmfestival");
        List<Movie> movies = PojoFactory.getMovies(connection);
        PdfReader reader;
        PdfStamper stamper;
        ByteArrayOutputStream baos;
        // Loop over all the movies and fill out the data sheet
        for (Movie movie : movies) {
            reader = new PdfReader(DATASHEET);
            baos = new ByteArrayOutputStream();
            stamper = new PdfStamper(reader, baos);
            AcroFields fields = stamper.getAcroFields();
            fields.setGenerateAppearances(true);
            fill(fields, movie);
            stamper.setFormFlattening(true);
            stamper.close();
            reader.close();
            
            reader = new PdfReader(baos.toByteArray());
            copy.addPage(copy.getImportedPage(reader, 1));
            copy.freeReader(reader);
            reader.close();
        }
        // Close the database connection
        connection.close();
    }
}
DataSheets2.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part2.chapter06;
 
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.pdf.PdfSmartCopy;
 
public class DataSheets2 extends DataSheets1 {
 
    /** The resulting PDF file. */
    public static final String RESULT
        = "results/part2/chapter06/datasheets2.pdf";
    
    /**
     * Main method.
     * @param args no arguments needed
     * @throws DocumentException 
     * @throws IOException
     * @throws SQLException
     */
    public static void main(String[] args)
        throws IOException, SQLException, DocumentException {
        new DataSheets2().createPdf(RESULT);
    }
 
    /**
     * Creates a PDF document.
     * @param filename the path to the new PDF document
     * @throws    DocumentException 
     * @throws    IOException
     * @throws    SQLException
     */
    public void createPdf(String filename)
        throws IOException, DocumentException, SQLException {
        // step 1
        Document document = new Document();
        // step 2
        PdfSmartCopy copy
            = new PdfSmartCopy(document, new FileOutputStream(filename));
        // step 3
        document.open();
        // step 4
        addDataSheets(copy);
        // step 5
        document.close();
    }
}
ConcatenateForms1.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part2.chapter06;
 
import java.io.FileOutputStream;
import java.io.IOException;
 
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.PdfCopyFields;
import com.itextpdf.text.pdf.PdfReader;
 
public class ConcatenateForms1 {
 
    /** The original PDF file. */
    public static final String DATASHEET
        = "resources/pdfs/datasheet.pdf";
    /** The resulting PDF file. */
    public static final String RESULT
        = "results/part2/chapter06/concatenated_forms1.pdf";
    
    /**
     * Main method.
     * @param args no arguments needed
     * @throws DocumentException 
     * @throws IOException
     */
    public static void main(String[] args)
        throws IOException, DocumentException {
        // Create a PdfCopyFields object
        PdfCopyFields copy
            = new PdfCopyFields(new FileOutputStream(RESULT));
        // add a document
        PdfReader reader1 = new PdfReader(DATASHEET);
        copy.addDocument(reader1);
        // add a document
        PdfReader reader2 = new PdfReader(DATASHEET);
        copy.addDocument(reader2);
        // close the PdfCopyFields object
        copy.close();
        reader1.close();
        reader2.close();
    }
}
ConcatenateForms2.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
 
package part2.chapter06;
 
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
 
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.PdfCopyFields;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
 
public class ConcatenateForms2 {
 
    /** The original PDF file. */
    public static final String DATASHEET
        = "resources/pdfs/datasheet.pdf";
    /** The resulting PDF file. */
    public static final String RESULT
        = "results/part2/chapter06/concatenated_forms2.pdf";
    
    /**
     * Main method.
     * @param    args    no arguments needed
     * @throws DocumentException 
     * @throws IOException
     */
    public static void main(String[] args)
        throws IOException, DocumentException {
        // Create a PdfCopyFields object
        PdfCopyFields copy
            = new PdfCopyFields(new FileOutputStream(RESULT));
        // add a document
        PdfReader reader1 = new PdfReader(renameFieldsIn(DATASHEET, 1));
        copy.addDocument(reader1);
        // add a document
        PdfReader reader2 = new PdfReader(renameFieldsIn(DATASHEET, 2));
        copy.addDocument(reader2);
        // Close the PdfCopyFields object
        copy.close();
        reader1.close();
        reader2.close();
    }
    
    /**
     * Renames the fields in an interactive form.
     * @param datasheet the path to the original form
     * @param i a number that needs to be appended to the field names
     * @return a byte[] containing an altered PDF file
     * @throws IOException
     * @throws DocumentException
     */
    private static byte[] renameFieldsIn(String datasheet, int i)
        throws IOException, DocumentException {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        // Create the stamper
        PdfStamper stamper = new PdfStamper(new PdfReader(datasheet), baos);
        // Get the fields
        AcroFields form = stamper.getAcroFields();
        // Loop over the fields
        Set<String> keys = new HashSet<String>(form.getFields().keySet());
        for (String key : keys) {
            // rename the fields
            form.renameField(key, String.format("%s_%d", key, i));
        }
        // close the stamper
        stamper.close();
        return baos.toByteArray();
    }
}
PageInformation.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
using System;
using System.IO;
using System.Text;
using iTextSharp.text;
using iTextSharp.text.pdf;
using Ionic.Zip;
using kuujinbo.iTextInAction2Ed.Chapter01;
using kuujinbo.iTextInAction2Ed.Chapter03;
using kuujinbo.iTextInAction2Ed.Chapter05;
 
namespace kuujinbo.iTextInAction2Ed.Chapter06 {
  public class PageInformation : IWriter {
// ===========================================================================
    public const string RESULT = "page_info.txt";
    public void Write(Stream stream) {
      IWriter[] iw = {
        new HelloWorldLandscape1(), new HelloWorldLandscape2(),
        new MovieTemplates(), new Hero1()
      }; 
      StringBuilder sb = new StringBuilder();       
      using (ZipFile zip = new ZipFile()) {
        foreach (IWriter w in iw) {
          // Create a reader
          byte[] pdf = Utility.PdfBytes(w);
          string fileName = Utility.ResultFileName(w.ToString() + ".pdf");
          Inspect(sb, pdf, fileName); 
          zip.AddEntry(fileName, pdf);  
        }
        zip.AddEntry(RESULT, sb.ToString());
        zip.Save(stream);
      }          
    }   
// ---------------------------------------------------------------------------
    /**
     * Inspect a PDF file and write the info to a txt file
     * @param writer StringBuilder
     * @param pdf PDF file bytes
     * @param fileName PDF filename
     */
    public static void Inspect(StringBuilder sb, byte[] pdf, string fileName) {
      PdfReader reader = new PdfReader(pdf);
      sb.Append(fileName);
      sb.Append(Environment.NewLine);
      sb.Append("Number of pages: ");
      sb.Append(reader.NumberOfPages);
      sb.Append(Environment.NewLine);
      Rectangle mediabox = reader.GetPageSize(1);
      sb.Append("Size of page 1: [");
      sb.Append(mediabox.Left);
      sb.Append(',');
      sb.Append(mediabox.Bottom);
      sb.Append(',');
      sb.Append(mediabox.Right);
      sb.Append(',');
      sb.Append(mediabox.Top);
      sb.Append("]");
      sb.Append(Environment.NewLine);
      sb.Append("Rotation of page 1: ");
      sb.Append(reader.GetPageRotation(1));
      sb.Append(Environment.NewLine);
      sb.Append("Page size with rotation of page 1: ");
      sb.Append(reader.GetPageSizeWithRotation(1));
      sb.Append(Environment.NewLine);
      sb.Append("Is rebuilt? ");
      sb.Append(reader.IsRebuilt().ToString());
      sb.Append(Environment.NewLine);
      sb.Append("Is encrypted? ");
      sb.Append(reader.IsEncrypted().ToString());
      sb.Append(Environment.NewLine);
      sb.Append(Environment.NewLine);
    }    
// ===========================================================================
  }
}
MemoryInfo.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
using System;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading;
using Ionic.Zip;
using iTextSharp.text;
using iTextSharp.text.pdf;
using kuujinbo.iTextInAction2Ed.Chapter03;
 
namespace kuujinbo.iTextInAction2Ed.Chapter06 {
  public class MemoryInfo : IWriter {
 
    /** The resulting PDF file. */
    public static readonly String RESULT
        = "memory_info.txt";
    public static readonly String RESULT0
        = "MovieTemplates.pdf";
    
    /**
     * Do a full read of a PDF file
     * @param writer a writer to a report file
     * @param filename the file to read
     * @throws IOException
     */
    public static void fullRead(StreamWriter writer, byte[] file){
        long before = GC.GetTotalMemory(true);
        PdfReader reader = new PdfReader(file);
        int num = reader.NumberOfPages;
        writer.WriteLine(String.Format("Number of pages: {0}", num));
        writer.WriteLine(String.Format("Memory used by full read: {0}",
                    GC.GetTotalMemory(true) - before));
        writer.Flush();
        reader.Close();
    }
    
    /**
     * Do a partial read of a PDF file
     * @param writer a writer to a report file
     * @param filename the file to read
     * @throws IOException
     */
    public static void partialRead(StreamWriter writer, byte[] file) {
        long before = GC.GetTotalMemory(true);
        PdfReader reader = new PdfReader(
                new RandomAccessFileOrArray(file), null);
        int num = reader.NumberOfPages;
        writer.WriteLine(String.Format("Number of pages: {0}", num));
        writer.WriteLine(String.Format("Memory used by partial read: {0}",
                    GC.GetTotalMemory(true) - before));
        writer.Flush();
        reader.Close();
    }
      
 
    /**
     * Makes sure all garbage is cleared from the memory.
     */
    private static void GarbageCollect()
    {
        try
        {
            GC.Collect();
            Thread.Sleep(200);
            GC.WaitForPendingFinalizers();
            Thread.Sleep(200);
            GC.Collect();
            Thread.Sleep(200);
            GC.WaitForPendingFinalizers();
            Thread.Sleep(200);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.StackTrace);
        }
    }
// ===========================================================================
    public void Write(Stream stream) {
        try
        {
            using (ZipFile zip = new ZipFile())
            {
                using (MemoryStream resultStream = new MemoryStream())
                {
                    using (StreamWriter sw = new StreamWriter(resultStream))
                    {
                        using (MemoryStream movies = new MemoryStream())
                        {
                            // step 1
                            MovieTemplates mt = new MovieTemplates();
                            mt.Write(movies);
                            zip.AddEntry(RESULT0, movies.ToArray());
 
                            // step 2
                            GarbageCollect();
                            // Do a full read
                            fullRead(sw, movies.ToArray());
                            // Do a partial read
                            partialRead(sw, movies.ToArray());
                            zip.AddEntry(RESULT, resultStream.ToArray());
                        }
                    }
                }
                zip.Save(stream);
            }
        }
        catch(Exception ex)
        {
            Console.WriteLine(ex.StackTrace);
        }
    }    
// ===========================================================================
  }
}
SelectPages.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
using System;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;
using Ionic.Zip;
using kuujinbo.iTextInAction2Ed.Chapter03;
 
namespace kuujinbo.iTextInAction2Ed.Chapter06 {
  public class SelectPages : IWriter {
// ===========================================================================
    /** A resulting PDF file. */
    public const String RESULT1 = "timetable_stamper.pdf";
    /** A resulting PDF file. */
    public const String RESULT2 = "timetable_copy.pdf"; 
// ---------------------------------------------------------------------------
    public void Write(Stream stream) {
      MovieTemplates mt = new MovieTemplates();
      byte[] pdf = Utility.PdfBytes(mt);
      PdfReader reader = new PdfReader(pdf);
      using (ZipFile zip = new ZipFile()) {
        reader.SelectPages("4-8");
        zip.AddEntry(RESULT1, ManipulateWithStamper(reader));
/*
 * can't figure out __WHY__, but if i don't reset the reader the example
 * will __NOT__ work!
 */
        reader = new PdfReader(pdf);
        reader.SelectPages("4-8"); 
        zip.AddEntry(RESULT2, ManipulateWithCopy(reader));       
        zip.AddEntry(Utility.ResultFileName(mt.ToString() + ".pdf"), pdf);
        zip.Save(stream);
      }
    }
// ---------------------------------------------------------------------------
    /**
     * Creates a new PDF based on the one in the reader
     * @param reader a reader with a PDF file
     */
    private byte[] ManipulateWithStamper(PdfReader reader) {
      using (MemoryStream ms = new MemoryStream()) {
        using ( PdfStamper stamper = new PdfStamper(reader, ms) ) {
        }
        return ms.ToArray();
      }    
    }
// ---------------------------------------------------------------------------
    /**
     * Creates a new PDF based on the one in the reader
     * @param reader a reader with a PDF file
     */
    private byte[] ManipulateWithCopy(PdfReader reader) {
      using (MemoryStream ms = new MemoryStream()) {
        int n = reader.NumberOfPages;
        using (Document document = new Document()) {
          using (PdfCopy copy = new PdfCopy(document, ms)) {
            document.Open();
            for (int i = 0; i < n;) {
              copy.AddPage(copy.GetImportedPage(reader, ++i));
            }
          }
        }
        return ms.ToArray();
      }
    }    
// ===========================================================================
  }
}
ImportingPages1.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
using System;
using System.IO;
using Ionic.Zip;
using iTextSharp.text;
using iTextSharp.text.pdf;
using kuujinbo.iTextInAction2Ed.Chapter03;
 
namespace kuujinbo.iTextInAction2Ed.Chapter06 {
  public class ImportingPages1 : IWriter {
// ===========================================================================
    public const string RESULT = "time_table_imported1.pdf";
// ---------------------------------------------------------------------------
    public void Write(Stream stream) {
      // Use old example to create PDF
      MovieTemplates mt = new MovieTemplates();
      byte[] pdf = Utility.PdfBytes(mt);
      using (ZipFile zip = new ZipFile()) { 
        using (MemoryStream ms = new MemoryStream()) {
          // step 1
          using (Document document = new Document()) {
            // step 2
            PdfWriter writer = PdfWriter.GetInstance(document, ms);
            // step 3
            document.Open();
            // step 4
            PdfPTable table = new PdfPTable(2);
            PdfReader reader = new PdfReader(pdf);
            int n = reader.NumberOfPages;
            PdfImportedPage page;
            for (int i = 1; i <= n; i++) {
              page = writer.GetImportedPage(reader, i);
              table.AddCell(Image.GetInstance(page));
            }
            document.Add(table);
          }
          zip.AddEntry(RESULT, ms.ToArray());           
        }
        zip.AddEntry(Utility.ResultFileName(mt.ToString() + ".pdf"), pdf);
        zip.Save(stream);
      }
   }
// ===========================================================================
  }
}
ImportingPages2.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
using System;
using System.IO;
using Ionic.Zip;
using iTextSharp.text;
using iTextSharp.text.pdf;
using kuujinbo.iTextInAction2Ed.Chapter03;
 
namespace kuujinbo.iTextInAction2Ed.Chapter06 {
  public class ImportingPages2 : IWriter {
// ===========================================================================
    public const string RESULT = "time_table_imported2.pdf";
// ---------------------------------------------------------------------------
    public void Write(Stream stream) {
      // Use old example to create PDF
      MovieTemplates mt = new MovieTemplates();
      byte[] pdf = Utility.PdfBytes(mt);
      using (ZipFile zip = new ZipFile()) { 
        using (MemoryStream ms = new MemoryStream()) {
          // step 1
          using (Document document = new Document()) {
            // step 2
            PdfWriter writer = PdfWriter.GetInstance(document, ms);
            // step 3
            document.Open();
            // step 4
            PdfPTable table = new PdfPTable(2);
            PdfReader reader = new PdfReader(pdf);
            int n = reader.NumberOfPages;
            PdfImportedPage page;
            for (int i = 1; i <= n; i++) {
              page = writer.GetImportedPage(reader, i);
              table.DefaultCell.Rotation = -reader.GetPageRotation(i);
              table.AddCell(Image.GetInstance(page));
            }
            document.Add(table);
          }
          zip.AddEntry(RESULT, ms.ToArray());           
        }
        zip.AddEntry(Utility.ResultFileName(mt.ToString() + ".pdf"), pdf);
        zip.Save(stream);
      }      
    }
// ===========================================================================
  }
}
Layers.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
using System;
using System.IO;
using Ionic.Zip;
using iTextSharp.text;
using iTextSharp.text.pdf;
 
namespace kuujinbo.iTextInAction2Ed.Chapter06 {
  public class Layers : IWriter {
// ===========================================================================
    /** The resulting PDF. */
    public const string SOURCE = "layers_orig.pdf";
    /** The resulting PDF. */
    public const string RESULT = "layers.pdf";    
// ---------------------------------------------------------------------------        
    public void Write(Stream stream) {
      using (ZipFile zip = new ZipFile()) { 
        byte[] pdf = new Layers().CreatePdf();        
 
        // Create a reader
        PdfReader reader = new PdfReader(pdf);
        // step 1
        using (MemoryStream ms = new MemoryStream()) { 
          using (Document document = new Document(PageSize.A5.Rotate())) {
            // step 2
            PdfWriter writer = PdfWriter.GetInstance(document, ms);
            // step 3
            document.Open();
            // step 4
            PdfContentByte canvas = writer.DirectContent;
            PdfImportedPage page;
            BaseFont bf = BaseFont.CreateFont(
              BaseFont.ZAPFDINGBATS, "", BaseFont.EMBEDDED
            );
            for (int i = 0; i < reader.NumberOfPages; ) {
              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,
                ((char)(181 + i)).ToString(),
                496, 150 + 50 * i, 0
              );
              canvas.EndText();
            }
          }        
          zip.AddEntry(RESULT, ms.ToArray());
        }
        zip.AddEntry(SOURCE, pdf);
        zip.Save(stream);
      }   
    }
// ---------------------------------------------------------------------------    
    /**
     * Creates a PDF document for PdfReader.
     */
    public byte[] CreatePdf() {
      // step 1
      using (MemoryStream ms = new MemoryStream()) {
        using (Document document = new Document(PageSize.POSTCARD, 30, 30, 30, 30)) {
        // step 2
          PdfWriter writer = PdfWriter.GetInstance(document, ms);
          // step 3
          document.Open();
          // step 4
          PdfContentByte under = writer.DirectContentUnder;
          // Page 1: a rectangle
          DrawRectangle(
            under, PageSize.POSTCARD.Width, PageSize.POSTCARD.Height
          );
          under.SetRGBColorFill(0xFF, 0xD7, 0x00);
          under.Rectangle(
            5, 5, PageSize.POSTCARD.Width - 10, PageSize.POSTCARD.Height - 10
          );
          under.Fill();
          document.NewPage();
          // Page 2: an image
          DrawRectangle(
            under, PageSize.POSTCARD.Width, PageSize.POSTCARD.Height
          );
          Image img = Image.GetInstance(Path.Combine(
            Utility.ResourceImage, "loa.jpg"
          ));
          img.SetAbsolutePosition(
            (PageSize.POSTCARD.Width - img.ScaledWidth) / 2,
            (PageSize.POSTCARD.Height - img.ScaledHeight) / 2
          );
          document.Add(img);
          document.NewPage();
          // Page 3: the words "Foobar Film Festival"
          DrawRectangle(
            under, PageSize.POSTCARD.Width, PageSize.POSTCARD.Height
          );
          Paragraph p = new Paragraph(
            "Foobar Film Festival", new Font(Font.FontFamily.HELVETICA, 22)
          );
          p.Alignment = Element.ALIGN_CENTER;
          document.Add(p);
          document.NewPage();
          // Page 4: the words "SOLD OUT"
          DrawRectangle(under, PageSize.POSTCARD.Width, PageSize.POSTCARD.Height);
          PdfContentByte over = writer.DirectContent;
          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();
        }
        return ms.ToArray();
      }
    }
// ---------------------------------------------------------------------------    
    /**
     * 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.FillOpacity = 0.6f;
      content.SetGState(state);
      content.SetRGBColorFill(0xFF, 0xFF, 0xFF);
      content.SetLineWidth(3);
      content.Rectangle(0, 0, width, height);
      content.FillStroke();
      content.RestoreState();
    }   
// ===========================================================================
  }
}
Superimposing.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.Com/examples/
 * This example only works with the AGPL version of iText.
 */
using System;
using System.IO;
using Ionic.Zip;
using iTextSharp.text;
using iTextSharp.text.pdf;
 
namespace kuujinbo.iTextInAction2Ed.Chapter06 {
  public class Superimposing : IWriter {
// ===========================================================================
    /** The resulting PDF. */
    public const string SOURCE = "opening.pdf";
    /** The resulting PDF. */
    public const string RESULT = "festival_opening.pdf";    
// ---------------------------------------------------------------------------        
    public void Write(Stream stream) {
      using (ZipFile zip = new ZipFile()) { 
        byte[] pdf = new Superimposing().CreatePdf();
        // Create a reader
        PdfReader reader = new PdfReader(pdf);
        using (MemoryStream ms = new MemoryStream()) {     
          // step 1
          using (Document document = new Document(PageSize.POSTCARD)) {
            // step 2
            PdfWriter writer = PdfWriter.GetInstance(document, ms);
            // step 3
            document.Open();
            // step 4
            PdfContentByte canvas = writer.DirectContent;
            PdfImportedPage page;
            for (int i = 1; i <= reader.NumberOfPages; i++) {
              page = writer.GetImportedPage(reader, i);
              canvas.AddTemplate(page, 1f, 0, 0, 1, 0, 0);
            }
          } 
          zip.AddEntry(RESULT, ms.ToArray());
        }
        zip.AddEntry(SOURCE, pdf);
        zip.Save(stream);            
      }        
    }
// ---------------------------------------------------------------------------    
    /**
     * Creates a PDF document for PdfReader.
     */
    public byte[] CreatePdf() {
      using (MemoryStream ms = new MemoryStream()) {
        // step 1
        using (Document document = new Document(PageSize.POSTCARD, 30, 30, 30, 30)) {
          // step 2
          PdfWriter writer = PdfWriter.GetInstance(document, ms);
          // step 3
          document.Open();
          // step 4
          PdfContentByte under = writer.DirectContentUnder;
          // page 1: rectangle
          under.SetRGBColorFill(0xFF, 0xD7, 0x00);
          under.Rectangle(5, 5,
              PageSize.POSTCARD.Width - 10, PageSize.POSTCARD.Height - 10);
          under.Fill();
          document.NewPage();
          // page 2: image
          Image img = Image.GetInstance(Path.Combine(
            Utility.ResourceImage, "loa.jpg"
          ));
          img.SetAbsolutePosition(
            (PageSize.POSTCARD.Width - img.ScaledWidth) / 2,
            (PageSize.POSTCARD.Height - img.ScaledHeight) / 2
          );
          document.Add(img);
          document.NewPage();
          // page 3: the words "Foobar Film Festival"
          Paragraph p = new Paragraph(
            "Foobar Film Festival", new Font(Font.FontFamily.HELVETICA, 22)
          );
          p.Alignment = Element.ALIGN_CENTER;
          document.Add(p);
          document.NewPage();
          // page 4: the words "SOLD OUT"
          PdfContentByte over = writer.DirectContent;
          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();
        }
        return ms.ToArray();
      }
    }  
// ===========================================================================
  }
}
Stationery.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.Com/examples/
 * This example only works with the AGPL version of iText.
 */
using System;
using System.IO;
using System.Data;
using System.Data.Common;
using Ionic.Zip;
using iTextSharp.text;
using iTextSharp.text.pdf;
using kuujinbo.iTextInAction2Ed.Intro_1_2;
 
namespace kuujinbo.iTextInAction2Ed.Chapter06 {
  public class Stationery : IWriter {
// ===========================================================================
    /** The original PDF. */
    public const string STATIONERY = "stationery.pdf";
    /** The resulting PDF. */
    public const string RESULT = "text_on_stationery.pdf";
// --------------------------------------------------------------------------- 
    public void Write(Stream stream) {
      using (ZipFile zip = new ZipFile()) {
// create first PDF        
        byte[] stationary  = CreateStationary();
        zip.AddEntry(STATIONERY, stationary);
        zip.AddEntry(RESULT, CreatePdf(stationary));
        zip.Save(stream);
      }
    }
// --------------------------------------------------------------------------- 
    /**
     * Creates a PDF document.
     * @param stationary byte array of the new PDF document
     */   
    public byte[] CreatePdf(byte[] stationary) {
      using (MemoryStream ms = new MemoryStream()) {
        // step 1
        using (Document document = new Document(PageSize.A4, 36, 36, 72, 36)) {
          // step 2
          PdfWriter writer = PdfWriter.GetInstance(document, ms);
          //writer.CloseStream = false;
          UseStationary(writer, stationary);
          // step 3
          document.Open();
          // step 4
          string SQL = "SELECT country, id FROM film_country ORDER BY country";
          using (var c =  AdoDB.Provider.CreateConnection()) {
            c.ConnectionString = AdoDB.CS;
            using (DbCommand cmd = c.CreateCommand()) {
              cmd.CommandText = SQL;        
              c.Open();
              using (var r = cmd.ExecuteReader()) {
                while (r.Read()) {
                  document.Add(new Paragraph(
                    r["country"].ToString(), FilmFonts.BOLD
                  ));
                  document.Add(Chunk.NEWLINE);          
                  string id = r["id"].ToString();
                  foreach (Movie movie in PojoFactory.GetMovies(id, true)) {
                    document.Add(new Paragraph(
                      movie.MovieTitle, FilmFonts.BOLD
                    ));
                    if (!string.IsNullOrEmpty(movie.OriginalTitle)) {
                      document.Add(new Paragraph(
                        movie.OriginalTitle, FilmFonts.ITALIC
                      ));
                    }
                    document.Add(new Paragraph(
                      string.Format(
                        "Year: {0}; run length: {0} minutes",
                        movie.Year, movie.Duration
                      ), 
                      FilmFonts.NORMAL
                    ));
                    document.Add(PojoToElementFactory.GetDirectorList(movie));
                  }
                  document.NewPage();              
                }
              }
            }
          }
        }
        return ms.ToArray();
      }
    }
// ---------------------------------------------------------------------------    
    /** Imported page with the stationery. */
    private PdfImportedPage page;
 
    /**
     * Initialize the imported page.
     * @param writer The PdfWriter
     */
    public void UseStationary(PdfWriter writer, byte[] stationary) {
      writer.PageEvent = new TemplateHelper(this);
      PdfReader reader = new PdfReader(stationary);
      page = writer.GetImportedPage(reader, 1);
    }
/*
 * ###########################################################################
 * Inner class to add template
 * ###########################################################################
*/
    class TemplateHelper : PdfPageEventHelper {
      private Stationery instance;
      public TemplateHelper() { }
      public TemplateHelper(Stationery instance) { 
        this.instance = instance;
      }
      /**
       * @see com.itextpdf.text.pdf.PdfPageEventHelper#onEndPage(
       *      com.itextpdf.text.pdf.PdfWriter, com.itextpdf.text.Document)
       */
      public override void OnEndPage(PdfWriter writer, Document document) {
        writer.DirectContentUnder.AddTemplate(instance.page, 0, 0);
      }
    }
// ---------------------------------------------------------------------------    
    /**
     * Creates a PDF document.
     */
    public byte[] CreateStationary() {
      using (MemoryStream ms = new MemoryStream()) {
        // step 1
        using (Document document = new Document()) {
          // step 2
          PdfWriter writer = PdfWriter.GetInstance(document, ms);
          writer.CloseStream = false;
          // step 3
          document.Open();
          // step 4
          PdfPTable table = new PdfPTable(1);
          table.DefaultCell.HorizontalAlignment = Element.ALIGN_CENTER;
          table.AddCell(new Phrase("FOOBAR FILM FESTIVAL", FilmFonts.BOLD));
          document.Add(table);
          Font font = new Font(
            Font.FontFamily.HELVETICA, 52, Font.BOLD, new GrayColor(0.75f)
          );
          ColumnText.ShowTextAligned(
            writer.DirectContentUnder,
            Element.ALIGN_CENTER, new Phrase("FOOBAR FILM FESTIVAL", font),
            297.5f, 421, 45
          );
        }
        return ms.ToArray();
      }      
    }    
// ===========================================================================
  }
}
NUpTool.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.Com/examples/
 * This example only works with the AGPL version of iText.
 */
using System;
using System.IO;
using Ionic.Zip;
using iTextSharp.text;
using iTextSharp.text.pdf;
 
namespace kuujinbo.iTextInAction2Ed.Chapter06 {
  public class NUpTool : IWriter {
// ===========================================================================
    public const String RESULT = "result{0}up.pdf";
// ---------------------------------------------------------------------------     
    public void Write(Stream stream) {
      using (ZipFile zip = new ZipFile()) {
        // previous example
        Stationery s = new Stationery();
        byte[] stationary  = s.CreatePdf(s.CreateStationary());
        // reader for the src file
        PdfReader reader = new PdfReader(stationary);
        // initializations
        int pow = 1;
               
        do {
          Rectangle pageSize = reader.GetPageSize(1); 
          Rectangle newSize = (pow % 2) == 0 
            ? new Rectangle(pageSize.Width, pageSize.Height)
            : new Rectangle(pageSize.Height, pageSize.Width)
          ;
          Rectangle unitSize = new Rectangle(pageSize.Width, pageSize.Height);
          for (int i = 0; i < pow; i++) {
            unitSize = new Rectangle(unitSize.Height / 2, unitSize.Width);
          }
          int n = (int)Math.Pow(2, pow);
          int r = (int)Math.Pow(2, pow / 2);
          int c = n / r;           
          
          using (MemoryStream ms = new MemoryStream()) {
            // step 1
            using (Document document = new Document(newSize, 0, 0, 0, 0)) {
              // step 2
              PdfWriter writer = PdfWriter.GetInstance(document, ms);
              // step 3
              document.Open();
              // step 4
              PdfContentByte cb = writer.DirectContent;
              PdfImportedPage page;
              Rectangle currentSize;
              float offsetX, offsetY, factor;
              int total = reader.NumberOfPages;
              
              for (int i = 0; i < total; ) {
                if (i % n == 0) {
                  document.NewPage();
                }
                currentSize = reader.GetPageSize(++i);
                factor = Math.Min(
                    unitSize.Width / currentSize.Width,
                    unitSize.Height / currentSize.Height
                );
                offsetX = unitSize.Width * ((i % n) % c)
                  + (unitSize.Width - (currentSize.Width * factor)) / 2f
                ;
                offsetY = newSize.Height
                  - (unitSize.Height * (((i % n) / c) + 1))
                  + (unitSize.Height - (currentSize.Height * factor)) / 2f
                ;
                page = writer.GetImportedPage(reader, i);
                cb.AddTemplate(page, factor, 0, 0, factor, offsetX, offsetY);
              }
            }
            zip.AddEntry(string.Format(RESULT, n), ms.ToArray());
            ++pow;
          }
        } while (pow < 5); 
        zip.AddEntry(Utility.ResultFileName(s.ToString() + ".pdf"), stationary);
        zip.Save(stream);
      }
    }
// ===========================================================================
  }
}
TilingHero.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
using System;
using System.IO;
using Ionic.Zip;
using iTextSharp.text;
using iTextSharp.text.pdf;
 
namespace kuujinbo.iTextInAction2Ed.Chapter06 {
  public class TilingHero : IWriter {
// ===========================================================================
    public const String RESOURCE = "Hero.pdf";
    public const String RESULT = "superman.pdf";
// ---------------------------------------------------------------------------         
    public void Write(Stream stream) {
      // Creating a reader
      string resource = Path.Combine(Utility.ResourcePdf, RESOURCE);
      PdfReader reader = new PdfReader(resource);
      Rectangle pagesize = reader.GetPageSizeWithRotation(1); 
      using (ZipFile zip = new ZipFile()) {
        // step 1
        using (MemoryStream ms = new MemoryStream()) {
          using (Document document = new Document(pagesize)) {
            // step 2
            PdfWriter writer = PdfWriter.GetInstance(document, ms);
            // step 3
            document.Open();
            // step 4
            PdfContentByte content = writer.DirectContent;
            PdfImportedPage page = writer.GetImportedPage(reader, 1);
            // adding the same page 16 times with a different offset
            float x, y;
            for (int i = 0; i < 16; i++) {
              x = -pagesize.Width * (i % 4);
              y = pagesize.Height * (i / 4 - 3);
              content.AddTemplate(page, 4, 0, 0, 4, x, y);
              document.NewPage();
            }
          }
          zip.AddEntry(RESULT, ms.ToArray());
        }
        zip.AddFile(resource, "");
        zip.Save(stream);
      }
    }
// ===========================================================================
  }
}
StampText.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
using System;
using System.IO; 
using Ionic.Zip;
using iTextSharp.text;
using iTextSharp.text.pdf;
using kuujinbo.iTextInAction2Ed.Chapter01;
 
namespace kuujinbo.iTextInAction2Ed.Chapter06 {
  public class StampText : IWriter {
// ===========================================================================
  /** A resulting PDF file. */
    public const string RESULT1 = "hello1.pdf";
  /** A resulting PDF file. */
    public const string RESULT2 = "hello2.pdf";
  /** A resulting PDF file. */
    public const string RESULT3 = "hello3.pdf";
// ---------------------------------------------------------------------------        
    public void Write(Stream stream) {
      HelloWorldLandscape1 h1 = new HelloWorldLandscape1();
      byte[] h1b = Utility.PdfBytes(h1);
      HelloWorldLandscape2 h2 = new HelloWorldLandscape2();
      byte[] h2b = Utility.PdfBytes(h2);
 
      using (ZipFile zip = new ZipFile()) {
        zip.AddEntry(RESULT1, Stamp(h1b));
        zip.AddEntry(RESULT2, StampIgnoreRotation(h1b));
        zip.AddEntry(RESULT3, Stamp(h2b));
 
        zip.AddEntry(Utility.ResultFileName(h1.ToString() + ".pdf"), h1b);
        zip.AddEntry(Utility.ResultFileName(h2.ToString() + ".pdf"), h2b);
        zip.Save(stream);
      }
    }
// ---------------------------------------------------------------------------
    /**
     * Manipulates a PDF file src with the file dest as result
     * @param resource the original PDF
     */
    public static byte[] Stamp(byte[] resource) {
      PdfReader reader = new PdfReader(resource);
      using (var ms = new MemoryStream()) {
        using (PdfStamper stamper = new PdfStamper(reader, ms)) {
          PdfContentByte canvas = stamper.GetOverContent(1);
          ColumnText.ShowTextAligned(
            canvas,
            Element.ALIGN_LEFT, 
            new Phrase("Hello people!"), 
            36, 540, 0
          );
        }
        return ms.ToArray();
      }
    }
 
    /**
     * Manipulates a PDF file
     * @param resource the original PDF
     */
    public static byte[] StampIgnoreRotation(byte[] resource) {
      PdfReader reader = new PdfReader(resource);
      using (var ms = new MemoryStream()) {
        using (PdfStamper stamper = new PdfStamper(reader, ms)) {
          stamper.RotateContents = false;
          PdfContentByte canvas = stamper.GetOverContent(1);
          ColumnText.ShowTextAligned(
            canvas,
            Element.ALIGN_LEFT, 
            new Phrase("Hello people!"), 
            36, 540, 0
          );
        }
        return ms.ToArray();
      }    
    }    
// ===========================================================================
  }
}
TwoPasses.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
using System;
using System.IO;
using Ionic.Zip;
using System.Data;
using System.Data.Common;
using iTextSharp.text;
using iTextSharp.text.pdf;
using kuujinbo.iTextInAction2Ed.Intro_1_2;
 
namespace kuujinbo.iTextInAction2Ed.Chapter06 {
  public class TwoPasses : IWriter {
// ===========================================================================
    /** The resulting PDF file. */
    public const String RESULT = "page_x_of_y.pdf";
// ---------------------------------------------------------------------------         
    public void Write(Stream stream) {
      string SQL = "SELECT country, id FROM film_country ORDER BY country";
      using (ZipFile zip = new ZipFile()) {
        using (var ms = new MemoryStream()) {
          // FIRST PASS, CREATE THE PDF WITHOUT HEADER
          // step 1
          using (Document document = new Document(PageSize.A4, 36, 36, 54, 36)) {
            // step 2
            PdfWriter.GetInstance(document, ms);
            // step 3
            document.Open();
            // step 4
            using (var c =  AdoDB.Provider.CreateConnection()) {
              c.ConnectionString = AdoDB.CS;
              using (DbCommand cmd = c.CreateCommand()) {
                cmd.CommandText = SQL;          
                c.Open();
                using (var r = cmd.ExecuteReader()) {
                  while (r.Read()) {
                    document.Add(new Paragraph(
                      r["country"].ToString(), FilmFonts.BOLD
                    ));
                    document.Add(Chunk.NEWLINE);          
                    string id = r["id"].ToString();
                    foreach (Movie movie in PojoFactory.GetMovies(id, true)) {
                      document.Add(new Paragraph(
                        movie.MovieTitle, FilmFonts.BOLD
                      ));
                      if (!string.IsNullOrEmpty(movie.OriginalTitle)) {
                        document.Add(new Paragraph(
                          movie.OriginalTitle, FilmFonts.ITALIC
                        ));
                      }
                      document.Add(new Paragraph(string.Format(
                          "Year: {0}; run length: {0} minutes",
                          movie.Year, movie.Duration
                        ), 
                        FilmFonts.NORMAL
                      ));
                      document.Add(PojoToElementFactory.GetDirectorList(movie));
                    }
                    document.NewPage();              
                  }
                }
              }
            }
          }
          byte[] firstPass = ms.ToArray();
          zip.AddEntry("first-pass.pdf", firstPass);
 
          // SECOND PASS, ADD THE HEADER
          // Create a reader
          PdfReader reader = new PdfReader(firstPass);
          using (MemoryStream ms2 = new MemoryStream()) {
            // Create a stamper
            using (PdfStamper stamper = new PdfStamper(reader, ms2)) {
              // Loop over the pages and add a header to each page
              int n = reader.NumberOfPages;
              for (int i = 1; i <= n; i++) {
                GetHeaderTable(i, n).WriteSelectedRows(
                  0, -1, 34, 803, stamper.GetOverContent(i)
                );
              }
            }
            zip.AddEntry(RESULT, ms2.ToArray());
          }
        }
        zip.Save(stream);
      }        
    }
// ---------------------------------------------------------------------------    
    /**
     * 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.TotalWidth = 527;
      table.LockedWidth = true;
      table.DefaultCell.FixedHeight = 20;
      table.DefaultCell.Border = Rectangle.BOTTOM_BORDER;
      table.AddCell("FOOBAR FILMFESTIVAL");
      table.DefaultCell.HorizontalAlignment = Element.ALIGN_RIGHT;
      table.AddCell(string.Format("Page {0} of {1}", x, y));
      return table;
    }    
// ===========================================================================
  }
}
InsertPages.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
using System;
using System.IO;
using System.Data;
using System.Data.Common;
using Ionic.Zip;
using iTextSharp.text;
using iTextSharp.text.pdf;
using kuujinbo.iTextInAction2Ed.Intro_1_2;
 
namespace kuujinbo.iTextInAction2Ed.Chapter06 {
  public class InsertPages : IWriter {
// ===========================================================================
    public const string RESULT1 = "inserted_pages.pdf";
    public const string RESULT2 = "reordered.pdf";
// --------------------------------------------------------------------------- 
    public void Write(Stream stream) {
      using (ZipFile zip = new ZipFile()) {
        Stationery s = new Stationery();
        StampStationery ss = new StampStationery();
        byte[] stationery  = s.CreateStationary();
        byte[] sStationery = ss.ManipulatePdf(
          ss.CreatePdf(), stationery
        );
        byte[] insertPages = ManipulatePdf(sStationery, stationery);
        zip.AddEntry(RESULT1, insertPages); 
        // reorder the pages in the PDF
        PdfReader reader = new PdfReader(insertPages);
        reader.SelectPages("3-41,1-2");
        using (MemoryStream ms = new MemoryStream()) {
          using (PdfStamper stamper = new PdfStamper(reader, ms)) {
          }
          zip.AddEntry(RESULT2, ms.ToArray());
        }
        zip.AddEntry(Utility.ResultFileName(s.ToString() + ".pdf"), stationery);
        zip.AddEntry(Utility.ResultFileName(ss.ToString() + ".pdf"), sStationery);
        zip.Save(stream);          
      }
    }
// ---------------------------------------------------------------------------
    /**
     * Manipulates a PDF file src
     * @param src the original PDF
     * @param stationery the resulting PDF
     */
    public byte[] ManipulatePdf(byte[] src, byte[] stationery) {
      ColumnText ct = new ColumnText(null);
      string SQL = 
@"SELECT country, id FROM film_country 
ORDER BY country
";        
      using (var c =  AdoDB.Provider.CreateConnection()) {
        c.ConnectionString = AdoDB.CS;
        using (DbCommand cmd = c.CreateCommand()) {
          cmd.CommandText = SQL;
          c.Open();
          using (var r = cmd.ExecuteReader()) {
            while (r.Read()) {
              ct.AddElement(new Paragraph(
                24, new Chunk(r["country"].ToString())
              ));
            }
          }
        }
      }
      // Create a reader for the original document and for the stationery
      PdfReader reader = new PdfReader(src);
      PdfReader rStationery = new PdfReader(stationery);
      using (MemoryStream ms = new MemoryStream()) {
        // Create a stamper
        using (PdfStamper stamper = new PdfStamper(reader, ms)) {
          // Create an imported page for the stationery
          PdfImportedPage page = stamper.GetImportedPage(rStationery, 1);
          int i = 0;
          // Add the content of the ColumnText object 
          while(true) {
          // Add a new page
            stamper.InsertPage(++i, reader.GetPageSize(1));
            // Add the stationary to the new page
            stamper.GetUnderContent(i).AddTemplate(page, 0, 0);
            // Add as much content of the column as possible
            ct.Canvas = stamper.GetOverContent(i);
            ct.SetSimpleColumn(36, 36, 559, 770);
            if (!ColumnText.HasMoreText(ct.Go()))
                break;
          }
        }
        return ms.ToArray();     
      }
    }    
// ===========================================================================
  }
}
FormInformation.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
using System;
using System.IO;
using System.Text;
using Ionic.Zip;
using iTextSharp.text;
using iTextSharp.text.pdf;
 
namespace kuujinbo.iTextInAction2Ed.Chapter06 {
  public class FormInformation : IWriter {
// ===========================================================================
    public const string RESULT = "form_info.txt";
// --------------------------------------------------------------------------- 
    public void Write(Stream stream) {
      string datasheet = Path.Combine(Utility.ResourcePdf, "datasheet.pdf"); 
      using (ZipFile zip = new ZipFile()) { 
        // Create a reader to extract info
        PdfReader reader = new PdfReader(datasheet);
        // Get the fields from the reader (read-only!!!)
        AcroFields form = reader.AcroFields;
        // Loop over the fields and get info about them 
        StringBuilder sb = new StringBuilder();       
        foreach (string key in form.Fields.Keys) {
          sb.Append(key);
          sb.Append(": ");
          switch (form.GetFieldType(key)) {
            case AcroFields.FIELD_TYPE_CHECKBOX:
              sb.Append("Checkbox");
              break;
            case AcroFields.FIELD_TYPE_COMBO:
              sb.Append("Combobox");
              break;
            case AcroFields.FIELD_TYPE_LIST:
              sb.Append("List");
              break;
            case AcroFields.FIELD_TYPE_NONE:
              sb.Append("None");
              break;
            case AcroFields.FIELD_TYPE_PUSHBUTTON:
              sb.Append("Pushbutton");
              break;
            case AcroFields.FIELD_TYPE_RADIOBUTTON:
              sb.Append("Radiobutton");
              break;
            case AcroFields.FIELD_TYPE_SIGNATURE:
              sb.Append("Signature");
              break;
            case AcroFields.FIELD_TYPE_TEXT:
              sb.Append("Text");
              break;
            default:
              sb.Append("?");
              break;
          }
          sb.Append(Environment.NewLine);
        } 
        
        // Get possible values for field "CP_1"
        sb.Append("Possible values for CP_1:");
        sb.Append(Environment.NewLine);
        string[] states = form.GetAppearanceStates("CP_1");
        for (int i = 0; i < states.Length; i++) {
          sb.Append(" - ");
          sb.Append(states[i]);
          sb.Append(Environment.NewLine);
        }
 
        // Get possible values for field "category"
        sb.Append("Possible values for category:");
        sb.Append(Environment.NewLine);
        states = form.GetAppearanceStates("category");
        for (int i = 0; i < states.Length - 1; i++) {
          sb.Append(states[i]);
          sb.Append(", ");
        }
        sb.Append(states[states.Length - 1]);
        
        zip.AddEntry(RESULT, sb.ToString());
        zip.AddFile(datasheet, "");
        zip.Save(stream);
      }      
    }
// ===========================================================================
  }
}
FillDataSheet.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Ionic.Zip;
using iTextSharp.text;
using iTextSharp.text.pdf;
using kuujinbo.iTextInAction2Ed.Intro_1_2;
/*
 * only run on localhost; requires write permissions
 * to the specified directory on a real web server
*/
namespace kuujinbo.iTextInAction2Ed.Chapter06 {
  public class FillDataSheet : IWriter {
// ===========================================================================
/** The original PDF file. */
    public const string DATASHEET = "datasheet.pdf";
/** Format for resulting PDF files. */
    public const string RESULT = "imdb{0}.pdf";    
// ---------------------------------------------------------------------------    
    public virtual void Write(Stream stream) {  
      using (ZipFile zip = new ZipFile()) { 
        // Get the movies
        IEnumerable<Movie> movies = PojoFactory.GetMovies();
        string datasheet = Path.Combine(Utility.ResourcePdf, DATASHEET); 
        string className = this.ToString();            
        // Fill out the data sheet form with data
        foreach (Movie movie in movies) {
          if (movie.Year < 2007) continue;
          PdfReader reader = new PdfReader(datasheet);          
          string dest = string.Format(RESULT, movie.Imdb);
          using (MemoryStream ms = new MemoryStream()) {
            using (PdfStamper stamper = new PdfStamper(reader, ms)) {
              AcroFields fields = stamper.AcroFields;
              fields.GenerateAppearances = true;
              Fill(fields, movie);
              if (movie.Year == 2007) stamper.FormFlattening = true;
            }
            zip.AddEntry(dest, ms.ToArray());
          }         
        }
        zip.AddFile(datasheet, "");
        zip.Save(stream);
      }              
    }
// ---------------------------------------------------------------------------    
    /**
     * Fill out the fields using info from a Movie object.
     * @param form The form object
     * @param movie A movie POJO
     */
    public static void Fill(AcroFields form, Movie movie) {
      form.SetField("title", movie.MovieTitle);
      form.SetField("director", GetDirectors(movie));
      form.SetField("year", movie.Year.ToString());
      form.SetField("duration", movie.Duration.ToString());
      form.SetField("category", movie.entry.category.Keyword);
      foreach (Screening screening in movie.entry.Screenings) {
        form.SetField(screening.Location.Replace('.', '_'), "Yes");
      }
    }
// ---------------------------------------------------------------------------    
    /**
     * Gets the directors from a Movie object,
     * and concatenates them in a String.
     * @param movie a Movie object
     * @return a String containing director names
     */
    public static String GetDirectors(Movie movie) {
      List<Director> directors = movie.Directors;
      StringBuilder buf = new StringBuilder();
      foreach (Director director in directors) {
        buf.Append(director.GivenName);
        buf.Append(' ');
        buf.Append(director.Name);
        buf.Append(',');
        buf.Append(' ');
      }
      int i = buf.Length;
      if (i > 0) buf.Length = i - 2;
      return buf.ToString();
    }    
// ===========================================================================
  }
}
Concatenate.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
using System;
using System.Collections.Generic;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;
using Ionic.Zip;
using kuujinbo.iTextInAction2Ed.Chapter02;
using kuujinbo.iTextInAction2Ed.Chapter05;
 
namespace kuujinbo.iTextInAction2Ed.Chapter06 {
  public class Concatenate : IWriter {
// ===========================================================================
    public const string RESULT = "concatenated.pdf";
// ---------------------------------------------------------------------------
    public void Write(Stream stream) {
      MovieLinks1 ml = new MovieLinks1();
      MovieHistory mh = new MovieHistory();
      List<byte[]> pdf = new List<byte[]>() {
        Utility.PdfBytes(ml),
        Utility.PdfBytes(mh)
      };
      string[] names = {ml.ToString(), mh.ToString()};
      using (ZipFile zip = new ZipFile()) { 
        using (MemoryStream ms = new MemoryStream()) {
          // step 1
          using (Document document = new Document()) {
            // step 2
            using (PdfCopy copy = new PdfCopy(document, ms)) {
              // step 3
              document.Open();
              // step 4
              for (int i = 0; i < pdf.Count; ++i) {
                zip.AddEntry(Utility.ResultFileName(names[i] + ".pdf"), pdf[i]);
                PdfReader reader = new PdfReader(pdf[i]);
                // loop over the pages in that document
                int n = reader.NumberOfPages;
                for (int page = 0; page < n; ) {
                  copy.AddPage(copy.GetImportedPage(reader, ++page));
                }
              }
            }
          }
          zip.AddEntry(RESULT, ms.ToArray());
        }
        zip.Save(stream);    
      }
    }
// ===========================================================================
  }
}
ConcatenateStamp.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
using System;
using System.IO;
using System.Collections.Generic;
using Ionic.Zip;
using iTextSharp.text;
using iTextSharp.text.pdf;
using kuujinbo.iTextInAction2Ed.Chapter02;
using kuujinbo.iTextInAction2Ed.Chapter05;
 
namespace kuujinbo.iTextInAction2Ed.Chapter06 {
  public class ConcatenateStamp : IWriter {
// ===========================================================================
    /** The resulting PDF file. */
    public const string RESULT = "concatenated_stamped.pdf";
// ---------------------------------------------------------------------------    
    public void Write(Stream stream) {   
      using (ZipFile zip = new ZipFile()) { 
        MovieLinks1 ml = new MovieLinks1();
        byte[] r1 = Utility.PdfBytes(ml);
        MovieHistory mh = new MovieHistory();
        byte[] r2 = Utility.PdfBytes(mh);
        using (MemoryStream ms = new MemoryStream()) {
          // step 1
          using (Document document = new Document()) {
            // step 2
            using (PdfCopy copy = new PdfCopy(document, ms)) {
              // step 3
              document.Open();
              // step 4
              // reader for document 1
              PdfReader reader1 = new PdfReader(r1);
              int n1 = reader1.NumberOfPages;
              // reader for document 2
              PdfReader reader2 = new PdfReader(r2);
              int n2 = reader2.NumberOfPages;
              // 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 {0} of {1}", 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 {0} of {1}", n1 + i, n1 + n2)),
                  297.5f, 28, 0
                );
                stamp.AlterContents();
                copy.AddPage(page);
              }   
            }   
          }
          zip.AddEntry(RESULT, ms.ToArray());          
          zip.AddEntry(Utility.ResultFileName(ml.ToString() + ".pdf"), r1);       
          zip.AddEntry(Utility.ResultFileName(mh.ToString()+ ".pdf"), r2); 
        }
        zip.Save(stream);
      }       
    }
// ===========================================================================
  }
}
Burst.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
using System;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;
using Ionic.Zip;
using kuujinbo.iTextInAction2Ed.Chapter03;
 
namespace kuujinbo.iTextInAction2Ed.Chapter06 {
  public class Burst : IWriter {
// ===========================================================================
/** Format of the resulting PDF files. */
    public const string RESULT = "timetable_p{0}.pdf";
// ---------------------------------------------------------------------------
    public void Write(Stream stream) {
      // use one of the previous examples to create a PDF
      MovieTemplates mt = new MovieTemplates();
      // Create a reader
      byte[] pdf = Utility.PdfBytes(mt);
      PdfReader reader = new PdfReader(pdf);
      // loop over all the pages in the original PDF
      int n = reader.NumberOfPages;      
      using (ZipFile zip = new ZipFile()) {
        for (int i = 0; i < n; ) {
          string dest = string.Format(RESULT, ++i);
          using (MemoryStream ms = new MemoryStream()) {
// We'll create as many new PDFs as there are pages
            // step 1
            using (Document document = new Document()) {
              // step 2
              using (PdfCopy copy = new PdfCopy(document, ms)) {
                // step 3
                document.Open();
                // step 4
                copy.AddPage(copy.GetImportedPage(reader, i));
              }
            }
            zip.AddEntry(dest, ms.ToArray());
          }
        }
        zip.AddEntry(Utility.ResultFileName(mt.ToString() + ".pdf"), pdf);
        zip.Save(stream);       
      }
    }
// ===========================================================================
  }
}
DataSheets1.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
using System;
using System.IO; 
using System.Collections.Generic; 
using Ionic.Zip;
using iTextSharp.text;
using iTextSharp.text.pdf;
using kuujinbo.iTextInAction2Ed.Intro_1_2;
 
namespace kuujinbo.iTextInAction2Ed.Chapter06 {
  public class DataSheets1 : FillDataSheet {
// ===========================================================================
    public new const string RESULT = "datasheets1.pdf";
    public readonly string DATASHEET_PATH = Path.Combine(Utility.ResourcePdf, DATASHEET);
// ---------------------------------------------------------------------------
    public override void Write(Stream stream) {
      using (ZipFile zip = new ZipFile()) { 
        using (MemoryStream ms = new MemoryStream()) {
          // step 1
          using (Document document = new Document()) {
            // step 2
            using (PdfCopy copy = new PdfCopy(document, ms)) {
              // step 3
              document.Open();
              // step 4
              AddDataSheets(copy);
            }
          }
          zip.AddEntry(RESULT, ms.ToArray());        
        }
        zip.AddFile(DATASHEET_PATH, "");
        zip.Save(stream);
      }
    }
// ---------------------------------------------------------------------------
    /**
     * Fills out a data sheet, flattens it, and adds it to a combined PDF.
     * @param copy the PdfCopy instance (can also be PdfSmartCopy)
     */
    public void AddDataSheets(PdfCopy copy) {
      IEnumerable<Movie> movies = PojoFactory.GetMovies();
      // Loop over all the movies and fill out the data sheet
      foreach (Movie movie in movies) {
        PdfReader reader = new PdfReader(DATASHEET_PATH);
        using (var ms = new MemoryStream()) {
          using (PdfStamper stamper = new PdfStamper(reader, ms)) {
            Fill(stamper.AcroFields, movie);
            stamper.FormFlattening = true;
          }
          reader = new PdfReader(ms.ToArray());
          copy.AddPage(copy.GetImportedPage(reader, 1));
        }
      }
    }    
// ===========================================================================
  }
}
DataSheets2.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
using System;
using System.IO; 
using System.Collections.Generic; 
using Ionic.Zip;
using iTextSharp.text;
using iTextSharp.text.pdf;
/*
 * this creates a bit of overhead, so we only run on localhost;
*/
namespace kuujinbo.iTextInAction2Ed.Chapter06 {
  public class DataSheets2 : DataSheets1 {
// ===========================================================================
    public new const string RESULT = "datasheets2.pdf";
// ---------------------------------------------------------------------------
    public override void Write(Stream stream) {
      using (ZipFile zip = new ZipFile()) { 
        using (MemoryStream ms = new MemoryStream()) {
          // step 1
          using (Document document = new Document()) {
            // step 2
            using (PdfSmartCopy copy = new PdfSmartCopy(document, ms)) {
              // step 3
              document.Open();
              // step 4
              AddDataSheets(copy);
            }
          }
          zip.AddEntry(RESULT, ms.ToArray());        
        }
        zip.AddFile(DATASHEET_PATH, "");
        zip.Save(stream);
      }    
    } 
// ===========================================================================
  }
}
ConcatenateForms1.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
using System;
using System.IO;
using Ionic.Zip;
using iTextSharp.text;
using iTextSharp.text.pdf;
 
namespace kuujinbo.iTextInAction2Ed.Chapter06 {
  public class ConcatenateForms1 : IWriter {
// ===========================================================================
    public const string RESULT = "concatenated_forms1.pdf";
    /** The original PDF file. */
    public const string copyName = "datasheet.pdf";
    public readonly string DATASHEET = Path.Combine(
      Utility.ResourcePdf, copyName
    );
// ---------------------------------------------------------------------------    
    public void Write(Stream stream) {
      using (ZipFile zip = new ZipFile()) {
        using (MemoryStream ms = new MemoryStream()) {
          // Create a PdfCopyFields object
          PdfCopyFields copy = new PdfCopyFields(ms);
          // add a document
          copy.AddDocument(new PdfReader(DATASHEET));
          // add a document
          copy.AddDocument(new PdfReader(DATASHEET));
          // close the PdfCopyFields object
          copy.Close();
          zip.AddEntry(RESULT, ms.ToArray());
        }
        zip.AddFile(DATASHEET, "");
        zip.Save(stream);
      }
    }
// ===========================================================================
  }
}
ConcatenateForms2.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
using System;
using System.IO;
using System.Collections.Generic;
using Ionic.Zip;
using iTextSharp.text;
using iTextSharp.text.pdf;
 
namespace kuujinbo.iTextInAction2Ed.Chapter06 {
  public class ConcatenateForms2 : IWriter {
// ===========================================================================
    public const string RESULT = "concatenated_forms2.pdf";
/** The original PDF file. */
    public const string copyName = "datasheet.pdf";
    public readonly string DATASHEET = Path.Combine(
      Utility.ResourcePdf, copyName
    );
// ---------------------------------------------------------------------------    
    public void Write(Stream stream) {   
      using (ZipFile zip = new ZipFile()) {
        using (MemoryStream ms = new MemoryStream()) {
          // Create a PdfCopyFields object
          PdfCopyFields copy = new PdfCopyFields(ms);
          // add a document
          copy.AddDocument(new PdfReader(RenameFieldsIn(
            DATASHEET, 1
          )));
          // add a document
          copy.AddDocument(new PdfReader(RenameFieldsIn(
            DATASHEET, 2
          )));
          // close the PdfCopyFields object
          copy.Close();
          zip.AddEntry(RESULT, ms.ToArray());            
        }
        zip.AddFile(DATASHEET, "");
        zip.Save(stream);        
      }     
    }
// ---------------------------------------------------------------------------    
    /**
     * Renames the fields in an interactive form.
     * @param datasheet the path to the original form
     * @param i a number that needs to be appended to the field names
     * @return a byte[] containing an altered PDF file
     */
    private static byte[] RenameFieldsIn(string datasheet, int i) {
      List<string> form_keys = new List<string>();
      using (var ms = new MemoryStream()) {
        // Create the stamper
        using (PdfStamper stamper = new PdfStamper(
          new PdfReader(datasheet), ms)) 
        {
          // Get the fields
          AcroFields form = stamper.AcroFields;
          // so we aren't hit with 'Collection was modified' exception
          foreach (string k in stamper.AcroFields.Fields.Keys) {
            form_keys.Add(k);
          }
          // Loop over the fields
          foreach (string key in form_keys) {
            // rename the fields
            form.RenameField(key, string.Format("{0}_{1}", key, i));
          }
        }
        return ms.ToArray();
      }
    }    
// ===========================================================================
  }
}
StampStationery.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/*
 * This class is part of the book "iText in Action - 2nd Edition"
 * written by Bruno Lowagie (ISBN: 9781935182610)
 * For more info, go to: http://itextpdf.com/examples/
 * This example only works with the AGPL version of iText.
 */
using System;
using System.IO;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Linq; 
using Ionic.Zip;
using iTextSharp.text;
using iTextSharp.text.pdf;
using kuujinbo.iTextInAction2Ed.Intro_1_2;
 
namespace kuujinbo.iTextInAction2Ed.Chapter06 {
  public class StampStationery : IWriter {
// ===========================================================================
    /** The original PDF file. */
    public const string ORIGINAL = "original.pdf";
    /** The resulting PDF. */
    public const string RESULT = "stamped_stationary.pdf";    
// --------------------------------------------------------------------------- 
    public void Write(Stream stream) {
      using (ZipFile zip = new ZipFile()) {
        // previous example
        Stationery s = new Stationery();
        StampStationery ss = new StampStationery();
        byte[] stationery  = s.CreateStationary();
        byte[] sStationery = ss.CreatePdf();
        
        zip.AddEntry(RESULT, ManipulatePdf(sStationery, stationery));
        zip.AddEntry(ORIGINAL, sStationery); 
        zip.AddEntry(Utility.ResultFileName(s.ToString() + ".pdf"), stationery); 
        zip.Save(stream);
      }      
    }
// ---------------------------------------------------------------------------
    /**
     * 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
     */
    public byte[] ManipulatePdf(byte[] src, byte[] stationery) {
      // Create readers
      PdfReader reader = new PdfReader(src);
      PdfReader s_reader = new PdfReader(stationery);
      using (MemoryStream ms = new MemoryStream()) {
        // Create the stamper
        using (PdfStamper stamper = new PdfStamper(reader, ms)) {
          // Add the stationery to each page
          PdfImportedPage page = stamper.GetImportedPage(s_reader, 1);
          int n = reader.NumberOfPages;
          PdfContentByte background;
          for (int i = 1; i <= n; i++) {
            background = stamper.GetUnderContent(i);
            background.AddTemplate(page, 0, 0);
          }
        } 
        return ms.ToArray();   
      }
    }  
// ---------------------------------------------------------------------------
    /**
     * Creates a PDF document.
     */
    public byte[] CreatePdf() {
      string SQL = 
@"SELECT country, id FROM film_country 
ORDER BY country
";     
      using (MemoryStream ms = new MemoryStream()) {     
        // step 1
        using (Document document = new Document(PageSize.A4, 36, 36, 72, 36)) {
          // step 2
          PdfWriter.GetInstance(document, ms);
          // step 3
          document.Open();
          // step 4 
          using (var c =  AdoDB.Provider.CreateConnection()) {
            c.ConnectionString = AdoDB.CS;
            using (DbCommand cmd = c.CreateCommand()) {
              cmd.CommandText = SQL;           
              c.Open();
              using (var r = cmd.ExecuteReader()) {
                while (r.Read()) {
                  document.Add(new Paragraph(
                    r["country"].ToString(), FilmFonts.BOLD
                  ));
                  document.Add(Chunk.NEWLINE);
                  foreach (Movie movie in 
                      PojoFactory.GetMovies(r["id"].ToString(), true)) 
                  {
                    document.Add(new Paragraph(
                      movie.MovieTitle, FilmFonts.BOLD
                    ));
                    if (!string.IsNullOrEmpty(movie.OriginalTitle))
                        document.Add(
                          new Paragraph(movie.OriginalTitle, FilmFonts.ITALIC
                        ));
                    document.Add(new Paragraph(
                        String.Format(
                          "Year: {0}; run length: {1} minutes",
                          movie.Year, movie.Duration
                        ), 
                        FilmFonts.NORMAL
                    ));
                    document.Add(PojoToElementFactory.GetDirectorList(movie));
                  }
                  document.NewPage();              
                }
              }
            }
          }
        }
        return ms.ToArray();
      }
    }
// ===========================================================================
  }
}


Contact

Still have questions? 

We're happy to answer your questions. Reach out to us and we'll get back to you shortly.

Contact us
Stay updated

Join 11,000+ subscribers and become an iText PDF expert by staying up to date with our new products, updates, tips, technical solutions and happenings.

Subscribe Now