Chapter 16: PDF streams

10th October 2015
admin-marketing

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

SpecialId.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 part4.chapter16;
 
import java.io.FileOutputStream;
import java.io.IOException;
 
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PdfImage;
import com.itextpdf.text.pdf.PdfIndirectObject;
import com.itextpdf.text.pdf.PdfName;
import com.itextpdf.text.pdf.PdfWriter;
 
public class SpecialId {
 
    /** The resulting PDF file. */
    public static String RESULT = "results/part4/chapter16/special_id.pdf";
    /** An image file. */
    public static String RESOURCE = "resources/img/bruno.jpg";
 
    /**
     * 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 {
        Document document = new Document(new Rectangle(400, 300));
        PdfWriter writer = PdfWriter.getInstance(document,
                new FileOutputStream(filename));
        document.open();
        Image img = Image.getInstance(RESOURCE);
        img.scaleAbsolute(400, 300);
        img.setAbsolutePosition(0, 0);
        PdfImage stream = new PdfImage(img, "", null);
        stream.put(new PdfName("ITXT_SpecialId"), new PdfName("123456789"));
        PdfIndirectObject ref = writer.addToBody(stream);
        img.setDirectReference(ref.getIndirectReference());
        document.add(img);
        document.close();
    }
 
    /**
     * Main method.
     *
     * @param    args    no arguments needed
     * @throws DocumentException 
     * @throws IOException
     */
    public static void main(String[] args) throws IOException, DocumentException {
        new SpecialId().createPdf(RESULT);
    }
}
ResizeImage.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
/*
 * 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 part4.chapter16;
 
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
 
import javax.imageio.ImageIO;
 
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.PRStream;
import com.itextpdf.text.pdf.PdfName;
import com.itextpdf.text.pdf.PdfNumber;
import com.itextpdf.text.pdf.PdfObject;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.parser.PdfImageObject;
 
public class ResizeImage {
 
    /** The resulting PDF file. */
    public static String RESULT = "results/part4/chapter16/resized_image.pdf";
    /** The multiplication factor for the image. */
    public static float FACTOR = 0.5f;
    
    /**
     * 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 {
        PdfName key = new PdfName("ITXT_SpecialId");
        PdfName value = new PdfName("123456789");
        // Read the file
        PdfReader reader = new PdfReader(SpecialId.RESULT);
        int n = reader.getXrefSize();
        PdfObject object;
        PRStream stream;
        // Look for image and manipulate image stream
        for (int i = 0; i < n; i++) {
            object = reader.getPdfObject(i);
            if (object == null || !object.isStream())
                continue;
            stream = (PRStream)object;
            if (value.equals(stream.get(key))) {
                PdfImageObject image = new PdfImageObject(stream);
                BufferedImage bi = image.getBufferedImage();
                if (bi == null) continue;
                int width = (int)(bi.getWidth() * FACTOR);
                int height = (int)(bi.getHeight() * FACTOR);
                BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
                AffineTransform at = AffineTransform.getScaleInstance(FACTOR, FACTOR);
                Graphics2D g = img.createGraphics();
                g.drawRenderedImage(bi, at);
                ByteArrayOutputStream imgBytes = new ByteArrayOutputStream();
                ImageIO.write(img, "JPG", imgBytes);
                stream.clear();
                stream.setData(imgBytes.toByteArray(), false, PRStream.NO_COMPRESSION);
                stream.put(PdfName.TYPE, PdfName.XOBJECT);
                stream.put(PdfName.SUBTYPE, PdfName.IMAGE);
                stream.put(key, value);
                stream.put(PdfName.FILTER, PdfName.DCTDECODE);
                stream.put(PdfName.WIDTH, new PdfNumber(width));
                stream.put(PdfName.HEIGHT, new PdfNumber(height));
                stream.put(PdfName.BITSPERCOMPONENT, new PdfNumber(8));
                stream.put(PdfName.COLORSPACE, PdfName.DEVICERGB);
            }
        }
        // Save altered PDF
        PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(RESULT));
        stamper.close();
        reader.close();
    }
 
    /**
     * Main method.
     *
     * @param    args    no arguments needed
     * @throws DocumentException 
     * @throws IOException
     */
    public static void main(String[] args) throws IOException, DocumentException {
        new SpecialId().createPdf(SpecialId.RESULT);
        new ResizeImage().manipulatePdf(SpecialId.RESULT, RESULT);
    }
}
ListUsedFonts.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 part4.chapter16;
 
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Set;
import java.util.TreeSet;
 
import part3.chapter11.FontTypes;
 
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.PdfDictionary;
import com.itextpdf.text.pdf.PdfName;
import com.itextpdf.text.pdf.PdfReader;
 
public class ListUsedFonts {
 
    /** The resulting PDF file. */
    public static String RESULT
        = "results/part4/chapter16/fonts.txt";
 
    /**
     * Creates a Set containing information about the fonts in the src PDF file.
     * @param src the path to a PDF file
     * @throws IOException
     */
    public Set<String> listFonts(String src) throws IOException {
        Set<String> set = new TreeSet<String>();
        PdfReader reader = new PdfReader(src);
        PdfDictionary resources;
        for (int k = 1; k <= reader.getNumberOfPages(); ++k) {
            resources = reader.getPageN(k).getAsDict(PdfName.RESOURCES);
            processResource(set, resources);
        }
        reader.close();
        return set;
    }
    
    /**
     * Extracts the font names from page or XObject resources.
     * @param set the set with the font names
     * @param resources the resources dictionary
     */
    public static void processResource(Set<String> set, PdfDictionary resource) {
        if (resource == null)
            return;
        PdfDictionary xobjects = resource.getAsDict(PdfName.XOBJECT);
        if (xobjects != null) {
            for (PdfName key : xobjects.getKeys()) {
                processResource(set, xobjects.getAsDict(key));
            }
        }
        PdfDictionary fonts = resource.getAsDict(PdfName.FONT);
        if (fonts == null)
            return;
        PdfDictionary font;
        for (PdfName key : fonts.getKeys()) {
            font = fonts.getAsDict(key);
            String name = font.getAsName(PdfName.BASEFONT).toString();
            if (name.length() > 8 && name.charAt(7) == '+') {
                name = String.format("%s subset (%s)", name.substring(8), name.substring(1, 7));
            }
            else {
                name = name.substring(1);
                PdfDictionary desc = font.getAsDict(PdfName.FONTDESCRIPTOR);
                if (desc == null)
                    name += " nofontdescriptor";
                else if (desc.get(PdfName.FONTFILE) != null)
                    name += " (Type 1) embedded";
                else if (desc.get(PdfName.FONTFILE2) != null)
                    name += " (TrueType) embedded";
                else if (desc.get(PdfName.FONTFILE3) != null)
                    name += " (" + font.getAsName(PdfName.SUBTYPE).toString().substring(1) + ") embedded";
            }
            set.add(name);
        }
    }
    
    /**
     * Main method.
     *
     * @param    args    no arguments needed
     * @throws DocumentException 
     * @throws IOException
     */
    public static void main(String[] args) throws IOException, DocumentException {
        new FontTypes().createPdf(FontTypes.RESULT);
        Set<String> set = new ListUsedFonts().listFonts(FontTypes.RESULT);
        PrintWriter out = new PrintWriter(new FileOutputStream(RESULT));
        for (String fontname : set)
            out.println(fontname);
        out.flush();
        out.close();
    }
}
EmbedFontPostFacto.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
/*
 * 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 part4.chapter16;
 
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
 
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Font;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfDictionary;
import com.itextpdf.text.pdf.PdfIndirectObject;
import com.itextpdf.text.pdf.PdfName;
import com.itextpdf.text.pdf.PdfNumber;
import com.itextpdf.text.pdf.PdfObject;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.PdfStream;
import com.itextpdf.text.pdf.PdfWriter;
 
public class EmbedFontPostFacto {
 
    /** The first resulting PDF file. */
    public static String RESULT1 = "results/part4/chapter16/without_font.pdf";
    /** The second resulting PDF file. */
    public static String RESULT2 = "results/part4/chapter16/with_font.pdf";
    /** A special font. */
    public static String FONT = "resources/fonts/wds011402.ttf";
    /** The name of the special font. */
    public static String FONTNAME = "WaltDisneyScriptv4.1";
 
    /**
     * 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();
        // step 2
        PdfWriter.getInstance(document, new FileOutputStream(filename));
        // step 3
        document.open();
        // step 4:
        Font font = new Font(BaseFont.createFont(FONT, "", BaseFont.NOT_EMBEDDED), 60);
        document.add(new Paragraph("iText in Action", font));
        // step 5
        document.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 void manipulatePdf(String src, String dest) throws IOException, DocumentException {
        // the font file
        RandomAccessFile raf = new RandomAccessFile(FONT, "r");
        byte fontfile[] = new byte[(int)raf.length()];
        raf.readFully(fontfile);
        raf.close();
        // create a new stream for the font file
        PdfStream stream = new PdfStream(fontfile);
        stream.flateCompress();
        stream.put(PdfName.LENGTH1, new PdfNumber(fontfile.length));
        // create a reader object
        PdfReader reader = new PdfReader(src);
        int n = reader.getXrefSize();
        PdfObject object;
        PdfDictionary font;
        PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
        PdfName fontname = new PdfName(FONTNAME);
        for (int i = 0; i < n; i++) {
            object = reader.getPdfObject(i);
            if (object == null || !object.isDictionary())
                continue;
            font = (PdfDictionary)object;
            if (PdfName.FONTDESCRIPTOR.equals(font.get(PdfName.TYPE))
                && fontname.equals(font.get(PdfName.FONTNAME))) {
                PdfIndirectObject objref = stamper.getWriter().addToBody(stream);
                font.put(PdfName.FONTFILE2, objref.getIndirectReference());
            }
        }
        stamper.close();
        reader.close();
    }
 
    /**
     * Main method.
     *
     * @param    args    no arguments needed
     * @throws DocumentException 
     * @throws IOException
     */
    public static void main(String[] args) throws IOException, DocumentException {
        EmbedFontPostFacto example = new EmbedFontPostFacto();
        example.createPdf(RESULT1);
        example.manipulatePdf(RESULT1, RESULT2);
    }
}
KubrickDvds.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
/*
 * 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 part4.chapter16;
 
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Set;
import java.util.TreeSet;
 
import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.List;
import com.itextpdf.text.ListItem;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PRStream;
import com.itextpdf.text.pdf.PdfAnnotation;
import com.itextpdf.text.pdf.PdfArray;
import com.itextpdf.text.pdf.PdfDictionary;
import com.itextpdf.text.pdf.PdfName;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfWriter;
import com.lowagie.database.DatabaseConnection;
import com.lowagie.database.HsqldbConnection;
import com.lowagie.filmfestival.Movie;
import com.lowagie.filmfestival.PojoFactory;
 
/**
 * Creates a PDF listing Stanley Kubrick movies and the corresponding posters.
 * JPGs of the movie posters are added as file attachment annotations.
 * The attachments can be extracted.
 */
public class KubrickDvds {
    
    /** Path to the resources. */
    public static final String RESOURCE
        = "resources/posters/%s.jpg";
    /** The filename of the resulting PDF. */
    public static final String FILENAME = "kubrick_dvds.pdf";
    /** The path to the resulting PDFs */
    public static final String PATH = "results/part4/chapter16/%s";
    /** The filename of the PDF with the movies by Stanley Kubrick. */
    public static final String RESULT = String.format(PATH, FILENAME);
    
    /**
     * Creates a PDF listing Stanley Kubrick movies in my DVD Collection. 
     * @throws IOException 
     * @throws DocumentException 
     * @throws SQLException
     */
    public static void main(String[] args) throws IOException, DocumentException, SQLException {
        KubrickDvds kubrick = new KubrickDvds();
        FileOutputStream os = new FileOutputStream(RESULT);
        os.write(kubrick.createPdf());
        os.flush();
        os.close();
        kubrick.extractAttachments(RESULT);
    }
    
    /**
     * Extracts attachments from an existing PDF.
     * @param src   the path to the existing PDF
     * @param dest  where to put the extracted attachments
     * @throws IOException
     */
    public void extractAttachments(String src) throws IOException {
        PdfReader reader = new PdfReader(src);
        PdfArray array;
        PdfDictionary annot;
        PdfDictionary fs;
        PdfDictionary refs;
        for (int i = 1; i <= reader.getNumberOfPages(); i++) {
            array = reader.getPageN(i).getAsArray(PdfName.ANNOTS);
            if (array == null) continue;
            for (int j = 0; j < array.size(); j++) {
                annot = array.getAsDict(j);
                if (PdfName.FILEATTACHMENT.equals(annot.getAsName(PdfName.SUBTYPE))) {
                    fs = annot.getAsDict(PdfName.FS);
                    refs = fs.getAsDict(PdfName.EF);
                    for (PdfName name : refs.getKeys()) {
                        FileOutputStream fos
                            = new FileOutputStream(String.format(PATH, fs.getAsString(name).toString()));
                        fos.write(PdfReader.getStreamBytes((PRStream)refs.getAsStream(name)));
                        fos.flush();
                        fos.close();
                    }
                }
            }
        }
        reader.close();
    }
 
    /**
     * Creates the PDF.
     * @return the bytes of a PDF file.
     * @throws DocumentExcetpion
     * @throws IOException
     * @throws SQLException 
     */
    public byte[] createPdf() throws DocumentException, IOException, SQLException {
        // step 1
        Document document = new Document();
        // step 2
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        PdfWriter writer = PdfWriter.getInstance(document, baos);
        // step 3
        document.open();
        // step 4
        document.add(new Paragraph("This is a list of Kubrick movies available in DVD stores."));
        PdfAnnotation annot;
        DatabaseConnection connection = new HsqldbConnection("filmfestival");
        Set<Movie> movies = new TreeSet<Movie>();
        movies.addAll(PojoFactory.getMovies(connection, 1));
        movies.addAll(PojoFactory.getMovies(connection, 4));
        ListItem item;
        Chunk chunk;
        List list = new List();
        for (Movie movie : movies) {
            annot = PdfAnnotation.createFileAttachment(
                    writer, null, movie.getMovieTitle(false), null,
                    String.format(RESOURCE, movie.getImdb()), String.format("%s.jpg", movie.getImdb()));
            item = new ListItem(movie.getMovieTitle(false));
            item.add("\u00a0\u00a0");
            chunk = new Chunk("\u00a0\u00a0\u00a0\u00a0");
            chunk.setAnnotation(annot);
            item.add(chunk);
            list.add(item);
        }
        document.add(list);
        // step 5
        document.close();
        connection.close();
        return baos.toByteArray();
    }
}
KubrickDocumentary.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
/*
 * 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 part4.chapter16;
 
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.sql.SQLException;
 
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.List;
import com.itextpdf.text.ListItem;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PRStream;
import com.itextpdf.text.pdf.PdfArray;
import com.itextpdf.text.pdf.PdfDictionary;
import com.itextpdf.text.pdf.PdfFileSpecification;
import com.itextpdf.text.pdf.PdfName;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.xml.XMLUtil;
import com.lowagie.database.DatabaseConnection;
import com.lowagie.database.HsqldbConnection;
import com.lowagie.filmfestival.Movie;
import com.lowagie.filmfestival.PojoFactory;
 
public class KubrickDocumentary {
    /** The filename of the PDF. */
    public static final String FILENAME = "kubrick_documentary.pdf";
    /** The path to the resulting PDFs */
    public static final String PATH = "results/part4/chapter16/%s";
    /** The filename of the PDF with the movies by Stanley Kubrick. */
    public static final String RESULT = String.format(PATH, FILENAME);
    
    /**
     * Creates the PDF.
     * @return the bytes of a PDF file.
     * @throws DocumentExcetpion
     * @throws IOException
     * @throws SQLException 
     */
    public byte[] createPdf() throws DocumentException, IOException, SQLException {
        DatabaseConnection connection = new HsqldbConnection("filmfestival");
        java.util.List<Movie> movies = PojoFactory.getMovies(connection, 1);
        connection.close();
        // step 1
        Document document = new Document();
        // step 2
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        PdfWriter writer = PdfWriter.getInstance(document, baos);
        // step 3
        document.open();
        // step 4
        document.add(new Paragraph(
            "'Stanley Kubrick: A Life in Pictures' is a documentary about Stanley Kubrick and his films:"));
 
        ByteArrayOutputStream txt = new ByteArrayOutputStream();
        PrintStream out = new PrintStream(txt);
        out.println("<movies>");
        List list = new List(List.UNORDERED, 20);
        ListItem item;
        for (Movie movie : movies) {
            out.println("<movie>");
            out.println(
                String.format("<title>%s</title>", XMLUtil.escapeXML(movie.getMovieTitle(), true)));
            out.println(String.format("<year>%s</year>", movie.getYear()));
            out.println(String.format("<duration>%s</duration>", movie.getDuration()));
            out.println("</movie>");
            item = new ListItem(movie.getMovieTitle());
            list.add(item);
        }
        document.add(list);
        out.print("</movies>");
        out.flush();
        out.close();
        PdfFileSpecification fs
          = PdfFileSpecification.fileEmbedded(writer,
                  null, "kubrick.xml", txt.toByteArray());
        writer.addFileAttachment(fs);
        // step 5
        document.close();
        return baos.toByteArray();
    }
    
    /**
     * Extracts document level attachments
     * @param filename     a file from which document level attachments will be extracted
     * @throws IOException
     */
    public void extractDocLevelAttachments(String filename) throws IOException {
        PdfReader reader = new PdfReader(filename);
        PdfDictionary root = reader.getCatalog();
        PdfDictionary documentnames = root.getAsDict(PdfName.NAMES);
        PdfDictionary embeddedfiles = documentnames.getAsDict(PdfName.EMBEDDEDFILES);
        PdfArray filespecs = embeddedfiles.getAsArray(PdfName.NAMES);
        PdfDictionary filespec;
        PdfDictionary refs;
        FileOutputStream fos;
        PRStream stream;
        for (int i = 0; i < filespecs.size(); ) {
          filespecs.getAsString(i++);
          filespec = filespecs.getAsDict(i++);
          refs = filespec.getAsDict(PdfName.EF);
          for (PdfName key : refs.getKeys()) {
            fos = new FileOutputStream(String.format(PATH, filespec.getAsString(key).toString()));
            stream = (PRStream) PdfReader.getPdfObject(refs.getAsIndirectObject(key));
            fos.write(PdfReader.getStreamBytes(stream));
            fos.flush();
            fos.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 {
        KubrickDocumentary kubrick = new KubrickDocumentary();
        FileOutputStream os = new FileOutputStream(RESULT);
        os.write(kubrick.createPdf());
        os.flush();
        os.close();
        kubrick.extractDocLevelAttachments(RESULT);
    }
}
KubrickBox.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
/*
 * 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 part4.chapter16;
 
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Set;
import java.util.TreeSet;
 
import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.FontFactory;
import com.itextpdf.text.Image;
import com.itextpdf.text.List;
import com.itextpdf.text.ListItem;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfAction;
import com.itextpdf.text.pdf.PdfDestination;
import com.itextpdf.text.pdf.PdfFileSpecification;
import com.itextpdf.text.pdf.PdfNumber;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.collection.PdfTargetDictionary;
import com.lowagie.database.DatabaseConnection;
import com.lowagie.database.HsqldbConnection;
import com.lowagie.filmfestival.Movie;
import com.lowagie.filmfestival.PojoFactory;
 
/**
 * This example explains the use of portable collections,
 * a new feature introduced in PDF 1.7
 */
public class KubrickBox {
 
    /** The resulting PDF. */
    public static final String RESULT = "results/part4/chapter16/kubrick_box.pdf";
    /** The path to an image used in the example. */
    public static final String IMG_BOX = "resources/img/kubrick_box.jpg";
    /** Path to the resources. */
    public static final String RESOURCE = "resources/posters/%s.jpg";
    /** The relative widths of the PdfPTable columns. */
    public static final float[] WIDTHS = { 1 , 7 };
 
    /**
     * Creates the PDF.
     * @return the bytes of a PDF file.
     * @throws DocumentException
     * @throws IOException
     * @throws SQLException 
     */
    public void createPdf(String filename) throws DocumentException, IOException, SQLException {
        // step 1
        Document document = new Document();
        // step 2
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(filename));
        // step 3
        document.open();
        // step 4
        Image img = Image.getInstance(IMG_BOX);
        document.add(img);
        List list = new List(List.UNORDERED, 20);
        PdfDestination dest = new PdfDestination(PdfDestination.FIT);
        dest.addFirst(new PdfNumber(1));
        PdfTargetDictionary target;
        Chunk chunk;
        ListItem item;
        PdfAction action = null;
        DatabaseConnection connection = new HsqldbConnection("filmfestival");
        Set<Movie> box = new TreeSet<Movie>();
        box.addAll(PojoFactory.getMovies(connection, 1));
        box.addAll(PojoFactory.getMovies(connection, 4));
        connection.close();
        PdfFileSpecification fs;
        for (Movie movie : box) {
            if (movie.getYear() > 1960) {
                fs = PdfFileSpecification.fileEmbedded(writer, null,
                        String.format("kubrick_%s.pdf", movie.getImdb()),
                        createMoviePage(movie));
                fs.addDescription(movie.getTitle(), false);
                writer.addFileAttachment(fs);
                item = new ListItem(movie.getMovieTitle());
                target = new PdfTargetDictionary(true);
                target.setEmbeddedFileName(movie.getTitle());
                action = PdfAction.gotoEmbedded(null, target, dest, true);
                chunk = new Chunk(" (see info)");
                chunk.setAction(action);
                item.add(chunk);
                list.add(item);
            }
        }
        document.add(list);
        // step 5
        document.close();
    }
 
    /**
     * Creates the PDF.
     * @return the bytes of a PDF file.
     * @throws DocumentExcetpion
     * @throws IOException
     * @throws SQLException 
     */
    public byte[] createMoviePage(Movie movie) throws DocumentException, IOException {
        // step 1
        Document document = new Document();
        // step 2
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        PdfWriter.getInstance(document, baos);
        // step 3
        document.open();
        // step 4
        Paragraph p = new Paragraph(movie.getMovieTitle(),
                FontFactory.getFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.NOT_EMBEDDED, 16));
        document.add(p);
        document.add(Chunk.NEWLINE);
        PdfPTable table = new PdfPTable(WIDTHS);
        table.addCell(Image.getInstance(String.format(RESOURCE, movie.getImdb())));
        PdfPCell cell = new PdfPCell();
        cell.addElement(new Paragraph("Year: " + movie.getYear()));
        cell.addElement(new Paragraph("Duration: " + movie.getDuration()));
        table.addCell(cell);
        document.add(table);
        PdfDestination dest = new PdfDestination(PdfDestination.FIT);
        dest.addFirst(new PdfNumber(1));
        PdfTargetDictionary target = new PdfTargetDictionary(false);
        Chunk chunk = new Chunk("Go to original document");
        PdfAction action = PdfAction.gotoEmbedded(null, target, dest, false);
        chunk.setAction(action);
        document.add(chunk);
        // step 5
        document.close();
        return baos.toByteArray();
    }
 
    /**
     * Main method.
     *
     * @param    args    no arguments needed
     * @throws DocumentException 
     * @throws IOException
     * @throws SQLException
     */
    public static void main(String[] args) throws DocumentException, IOException, SQLException {
        new KubrickBox().createPdf(RESULT);
    }
}
KubrickMovies.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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
/*
 * 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 part4.chapter16;
 
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.SQLException;
 
import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.FontFactory;
import com.itextpdf.text.Image;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfAction;
import com.itextpdf.text.pdf.PdfFileSpecification;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfString;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.collection.PdfCollection;
import com.itextpdf.text.pdf.collection.PdfCollectionField;
import com.itextpdf.text.pdf.collection.PdfCollectionItem;
import com.itextpdf.text.pdf.collection.PdfCollectionSchema;
import com.itextpdf.text.pdf.collection.PdfCollectionSort;
import com.itextpdf.text.pdf.collection.PdfTargetDictionary;
import com.lowagie.database.DatabaseConnection;
import com.lowagie.database.HsqldbConnection;
import com.lowagie.filmfestival.Movie;
import com.lowagie.filmfestival.PojoFactory;
 
public class KubrickMovies {
 
    /** Path to the resources. */
    public static final String RESOURCE
        = "resources/posters/%s.jpg";
    /** The relative widths of the PdfPTable columns. */
    public static final float[] WIDTHS = { 1 , 7 };
    
    /** The filename of the PDF. */
    public static final String FILENAME = "kubrick_movies.pdf";
    /** The filename of the PDF with the movies by Stanley Kubrick. */
    public static final String RESULT = "results/part4/chapter16/" + FILENAME;
    
    /**
     * Creates a Collection schema that can be used to organize the movies of Stanley Kubrick
     * in a collection: year, title, duration, DVD acquisition, filesize (filename is present, but hidden).
     * @return    a collection schema
     */
    private static PdfCollectionSchema getCollectionSchema() {
        PdfCollectionSchema schema = new PdfCollectionSchema();
        
        PdfCollectionField size = new PdfCollectionField("File size", PdfCollectionField.SIZE);
        size.setOrder(4);
        schema.addField("SIZE", size);
        
        PdfCollectionField filename = new PdfCollectionField("File name", PdfCollectionField.FILENAME);
        filename.setVisible(false);
        schema.addField("FILE", filename);
        
        PdfCollectionField title = new PdfCollectionField("Movie title", PdfCollectionField.TEXT);
        title.setOrder(1);
        schema.addField("TITLE", title);
        
        PdfCollectionField duration = new PdfCollectionField("Duration", PdfCollectionField.NUMBER);
        duration.setOrder(2);
        schema.addField("DURATION", duration);
        
        PdfCollectionField year = new PdfCollectionField("Year", PdfCollectionField.NUMBER);
        year.setOrder(0);
        schema.addField("YEAR", year);
        
        return schema;
    }
 
    /**
     * Creates the PDF.
     * @return the bytes of a PDF file.
     * @throws SQLException 
     */
    public byte[] createPdf() throws DocumentException, IOException, SQLException {
        // step 1
        Document document = new Document();
        // step 2
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        PdfWriter writer = PdfWriter.getInstance(document, baos);
        // step 3
        document.open();
        // step 4
        document.add(new Paragraph(
            "This document contains a collection of PDFs, one per Stanley Kubrick movie."));
        
        PdfCollection collection = new PdfCollection(PdfCollection.DETAILS);
        PdfCollectionSchema schema = getCollectionSchema(); 
        collection.setSchema(schema);
        PdfCollectionSort sort = new PdfCollectionSort("YEAR");
        sort.setSortOrder(false);
        collection.setSort(sort);
        collection.setInitialDocument("Eyes Wide Shut");
        writer.setCollection(collection);
        
        PdfFileSpecification fs;
        PdfCollectionItem item;
        DatabaseConnection connection = new HsqldbConnection("filmfestival");
        java.util.List<Movie> movies = PojoFactory.getMovies(connection, 1);
        connection.close();
        for (Movie movie : movies) {
            fs = PdfFileSpecification.fileEmbedded(writer, null,
                String.format("kubrick_%s.pdf", movie.getImdb()),
                createMoviePage(movie));
            fs.addDescription(movie.getTitle(), false);
 
            item = new PdfCollectionItem(schema);
            item.addItem("TITLE", movie.getMovieTitle(false));
            if (movie.getMovieTitle(true) != null) {
                item.setPrefix("TITLE", movie.getMovieTitle(true));
            }
            item.addItem("DURATION", movie.getDuration());
            item.addItem("YEAR", movie.getYear());
            fs.addCollectionItem(item);
            writer.addFileAttachment(fs);
        }
        // step 5
        document.close();
        return baos.toByteArray();
    }
 
    /**
     * Creates the PDF.
     * @return the bytes of a PDF file.
     */
    public byte[] createMoviePage(Movie movie) throws DocumentException, IOException {
        // step 1
        Document document = new Document();
        // step 2
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        PdfWriter.getInstance(document, baos);
        // step 3
        document.open();
        // step 4
        Paragraph p = new Paragraph(movie.getMovieTitle(),
            FontFactory.getFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.NOT_EMBEDDED, 16));
        document.add(p);
        document.add(Chunk.NEWLINE);
        PdfPTable table = new PdfPTable(WIDTHS);
        table.addCell(Image.getInstance(String.format(RESOURCE, movie.getImdb())));
        PdfPCell cell = new PdfPCell();
        cell.addElement(new Paragraph("Year: " + movie.getYear()));
        cell.addElement(new Paragraph("Duration: " + movie.getDuration()));
        table.addCell(cell);
        document.add(table);
        PdfTargetDictionary target = new PdfTargetDictionary(false);
        target.setAdditionalPath(new PdfTargetDictionary(false));
        Chunk chunk = new Chunk("Go to original document");
        PdfAction action = PdfAction.gotoEmbedded(null, target, new PdfString("movies"), false);
        chunk.setAction(action);
        document.add(chunk);
        // step 5
        document.close();
        return baos.toByteArray();
    }
 
    public static void main(String[] args) throws IOException, DocumentException, SQLException {
        KubrickMovies kubrick = new KubrickMovies();
        FileOutputStream os = new FileOutputStream(RESULT);
        os.write(kubrick.createPdf());
        os.flush();
        os.close();
    }
}
KubrickCollection.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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
/*
 * 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 part4.chapter16;
 
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.sql.SQLException;
import java.util.Set;
import java.util.TreeSet;
 
import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.List;
import com.itextpdf.text.ListItem;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.PdfAction;
import com.itextpdf.text.pdf.PdfDestination;
import com.itextpdf.text.pdf.PdfFileSpecification;
import com.itextpdf.text.pdf.PdfNumber;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.collection.PdfCollection;
import com.itextpdf.text.pdf.collection.PdfCollectionField;
import com.itextpdf.text.pdf.collection.PdfCollectionItem;
import com.itextpdf.text.pdf.collection.PdfCollectionSchema;
import com.itextpdf.text.pdf.collection.PdfCollectionSort;
import com.itextpdf.text.pdf.collection.PdfTargetDictionary;
import com.lowagie.database.DatabaseConnection;
import com.lowagie.database.HsqldbConnection;
import com.lowagie.filmfestival.Movie;
import com.lowagie.filmfestival.PojoFactory;
 
/**
 * This example explains the use of portable collections,
 * a new feature introduced in PDF 1.7
 */
public class KubrickCollection {
 
    /** An image file used in this example */
    public static final String IMG_BOX = "resources/img/kubrick_box.jpg";
    /** An image file used in this example */
    public static final String IMG_KUBRICK = "resources/img/kubrick.jpg";
    /** The resulting PDF file. */
    public static final String RESULT = "results/part4/chapter16/kubrick_collection.pdf";
    /** The name of a field in the collection schema. */
    public static final String TYPE_FIELD        = "TYPE";
    /** A caption of a field in the collection schema. */
    public static final String TYPE_CAPTION        = "File type";
    /** The name of a field in the collection schema. */
    public static final String FILE_FIELD        = "FILE";
    /** A caption of a field in the collection schema. */
    public static final String FILE_CAPTION        = "File name";
    /** Sort order for the keys in the collection. */
    public String[] KEYS = { TYPE_FIELD, FILE_FIELD };
    
    /**
     * Creates the PDF.
     * @return the bytes of a PDF file.
     * @throws SQLException 
     */
    public void createPdf(String filename) throws DocumentException, IOException, SQLException {
        // step 1
        Document document = new Document();
        // step 2
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(filename));
        // step 3
        document.open();
        // step 4
        PdfCollection collection = new PdfCollection(PdfCollection.HIDDEN);
        PdfCollectionSchema schema = getCollectionSchema();
        collection.setSchema(schema);
        PdfCollectionSort sort = new PdfCollectionSort(KEYS);
        collection.setSort(sort);
        writer.setCollection(collection);
 
        PdfCollectionItem collectionitem = new PdfCollectionItem(schema);
        PdfFileSpecification fs;
        fs = PdfFileSpecification.fileEmbedded(writer, IMG_KUBRICK, "kubrick.jpg", null);
        fs.addDescription("Stanley Kubrick", false);
        collectionitem.addItem(TYPE_FIELD, "JPEG");
        fs.addCollectionItem(collectionitem);
        writer.addFileAttachment(fs);
        
        ByteArrayOutputStream txt = new ByteArrayOutputStream();
        PrintStream out = new PrintStream(txt);
        Image img = Image.getInstance(IMG_BOX);
        document.add(img);
        List list = new List(List.UNORDERED, 20);
        PdfDestination dest = new PdfDestination(PdfDestination.FIT);
        dest.addFirst(new PdfNumber(1));
        PdfTargetDictionary intermediate;
        PdfTargetDictionary target;
        Chunk chunk;
        ListItem item;
        PdfAction action = null;
        DatabaseConnection connection = new HsqldbConnection("filmfestival");
        Set<Movie> box = new TreeSet<Movie>();
        java.util.List<Movie> movies = PojoFactory.getMovies(connection, 1);
        box.addAll(movies);
        box.addAll(PojoFactory.getMovies(connection, 4));
        connection.close();
        for (Movie movie : box) {
            if (movie.getYear() > 1960) {
                out.println(String.format(
                    "%s;%s;%s", movie.getMovieTitle(), movie.getYear(), movie.getDuration()));
                item = new ListItem(movie.getMovieTitle());
                if (!"0278736".equals(movie.getImdb())) {
                    target = new PdfTargetDictionary(true);
                    target.setEmbeddedFileName(movie.getTitle());
                    intermediate = new PdfTargetDictionary(true);
                    intermediate.setFileAttachmentPage(1);
                    intermediate.setFileAttachmentIndex(1);
                    intermediate.setAdditionalPath(target);
                    action = PdfAction.gotoEmbedded(null, intermediate, dest, true);
                    chunk = new Chunk(" (see info)");
                    chunk.setAction(action);
                    item.add(chunk);
                }
                list.add(item);
            }
        }
        out.flush();
        out.close();
        document.add(list);
        fs = PdfFileSpecification.fileEmbedded(writer, null, "kubrick.txt", txt.toByteArray());
        fs.addDescription("Kubrick box: the movies", false);
        collectionitem.addItem(TYPE_FIELD, "TXT");
        fs.addCollectionItem(collectionitem);
        writer.addFileAttachment(fs);
 
        PdfPTable table = new PdfPTable(1);
        table.setSpacingAfter(10);
        PdfPCell cell = new PdfPCell(new Phrase("All movies by Kubrick"));
        cell.setBorder(PdfPCell.NO_BORDER);
        fs = PdfFileSpecification.fileEmbedded(
            writer, null, KubrickMovies.FILENAME, new KubrickMovies().createPdf());
        collectionitem.addItem(TYPE_FIELD, "PDF");
        fs.addCollectionItem(collectionitem);
        target = new PdfTargetDictionary(true);
        target.setFileAttachmentPagename("movies");
        target.setFileAttachmentName("The movies of Stanley Kubrick");
        cell.setCellEvent(new PdfActionEvent(writer, PdfAction.gotoEmbedded(null, target, dest, true)));
        cell.setCellEvent(new FileAttachmentEvent(writer, fs, "The movies of Stanley Kubrick"));
        cell.setCellEvent(new LocalDestinationEvent(writer, "movies"));
        table.addCell(cell);
        writer.addFileAttachment(fs);
 
        cell = new PdfPCell(new Phrase("Kubrick DVDs"));
        cell.setBorder(PdfPCell.NO_BORDER);
        fs = PdfFileSpecification.fileEmbedded(
            writer, null, KubrickDvds.FILENAME, new KubrickDvds().createPdf());
        collectionitem.addItem(TYPE_FIELD, "PDF");
        fs.addCollectionItem(collectionitem);
        cell.setCellEvent(new FileAttachmentEvent(writer, fs, "Kubrick DVDs"));
        table.addCell(cell);
        writer.addFileAttachment(fs);
        
        cell = new PdfPCell(new Phrase("Kubrick documentary"));
        cell.setBorder(PdfPCell.NO_BORDER);
        fs = PdfFileSpecification.fileEmbedded(
            writer, null, KubrickDocumentary.FILENAME, new KubrickDocumentary().createPdf());
        collectionitem.addItem(TYPE_FIELD, "PDF");
        fs.addCollectionItem(collectionitem);
        cell.setCellEvent(new FileAttachmentEvent(writer, fs, "Kubrick Documentary"));
        table.addCell(cell);
        writer.addFileAttachment(fs);
 
        document.newPage();
        document.add(table);
        // step 5
        document.close();
    }
    
    /**
     * Creates a Collection schema that can be used to organize the movies of Stanley Kubrick
     * in a collection: year, title, duration, DVD acquisition, filesize (filename is present, but hidden).
     * @return    a collection schema
     */
    private static PdfCollectionSchema getCollectionSchema() {
        PdfCollectionSchema schema = new PdfCollectionSchema();
        
        PdfCollectionField type = new PdfCollectionField(TYPE_CAPTION, PdfCollectionField.TEXT);
        type.setOrder(0);
        schema.addField(TYPE_FIELD, type);
        
        PdfCollectionField filename = new PdfCollectionField(FILE_FIELD, PdfCollectionField.FILENAME);
        filename.setOrder(1);
        schema.addField(FILE_FIELD, filename);
        
        return schema;
    }
 
    /**
     * Main method.
     *
     * @param    args    no arguments needed
     * @throws DocumentException 
     * @throws IOException
     * @throws SQLException
     */
    public static void main(String[] args) throws DocumentException, IOException, SQLException {
        new KubrickCollection().createPdf(RESULT);
    }
}
FileAttachmentEvent.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
/*
 * 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 part4.chapter16;
 
import java.io.IOException;
 
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PdfAnnotation;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfFileSpecification;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPCellEvent;
import com.itextpdf.text.pdf.PdfWriter;
 
public class FileAttachmentEvent implements PdfPCellEvent {
 
    /** The PdfWriter to which the file has to be attached. */
    protected PdfWriter writer;
    /** The file specification that will be used to create an annotation. */
    protected PdfFileSpecification fs;
    /** The description that comes with the annotation. */
    protected String description;
    
    /**
     * Creates a FileAttachmentEvent.
     * 
     * @param writer      the writer to which the file attachment has to be added.
     * @param fs          the file specification.
     * @param description a description for the file attachment.
     */
    public FileAttachmentEvent(PdfWriter writer, PdfFileSpecification fs, String description) {
        this.writer = writer;
        this.fs = fs;
        this.description = description;
    }
    
    /**
     * Implementation of the cellLayout method.
     * @see com.itextpdf.text.pdf.PdfPCellEvent#cellLayout(
     *     com.itextpdf.text.pdf.PdfPCell, com.itextpdf.text.Rectangle, com.itextpdf.text.pdf.PdfContentByte[])
     */
    public void cellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvases) {
        try {
            PdfAnnotation annotation = PdfAnnotation.createFileAttachment(writer,
                new Rectangle(position.getLeft() - 20, position.getTop() - 15,
                    position.getLeft() - 5, position.getTop() - 5),
                description, fs);
            annotation.setName(description);
            writer.addAnnotation(annotation);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
PdfActionEvent.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
/*
 * 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 part4.chapter16;
 
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PdfAction;
import com.itextpdf.text.pdf.PdfAnnotation;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPCellEvent;
import com.itextpdf.text.pdf.PdfWriter;
 
public class PdfActionEvent implements PdfPCellEvent {
 
    /** The writer to which we are going to add the action. */
    protected PdfWriter writer;
    /** The action we're going to add. */
    protected PdfAction action;
    
    /** Creates a new Action event. */
    public PdfActionEvent(PdfWriter writer, PdfAction action) {
        this.writer = writer;
        this.action = action;
    }
    
    /** Implementation of the cellLayout method. */
    public void cellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvases) {
        writer.addAnnotation(new PdfAnnotation(writer,
            position.getLeft(), position.getBottom(), position.getRight(), position.getTop(),
            action));
    }
}
LocalDestinationEvent.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
/*
 * 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 part4.chapter16;
 
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfDestination;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPCellEvent;
import com.itextpdf.text.pdf.PdfWriter;
 
public class LocalDestinationEvent implements PdfPCellEvent {
 
    /** The writer to which the local destination will be added. */
    protected PdfWriter writer;
    /** The name of the local destination. */
    protected String name;
    
    /** Constructs a local destination event. */
    public LocalDestinationEvent(PdfWriter writer, String name) {
        this.writer = writer;
        this.name = name;
    }
    
    /** Implementation of the cellLayout method. */
    public void cellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvases) {
        writer.getDirectContent().localDestination(name,
            new PdfDestination(PdfDestination.FITH, position.getTop()));
    }
}
MovieAnnotation.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
/*
 * 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 part4.chapter16;
 
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.PdfAnnotation;
import com.itextpdf.text.pdf.PdfFileSpecification;
import com.itextpdf.text.pdf.PdfWriter;
 
public class MovieAnnotation {
 
    /** The resulting PDF file. */
    public static final String RESULT
        = "results/part4/chapter16/movie.pdf";
    /** One of the resources. */
    public static final String RESOURCE
        = "resources/img/foxdog.mpg";
    
    /**
     * 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();
        // step 2
        PdfWriter writer
          = PdfWriter.getInstance(document, new FileOutputStream(filename));
        // step 3
        document.open();
        // step 4
        PdfFileSpecification fs = PdfFileSpecification.fileEmbedded(writer,
                RESOURCE, "foxdog.mpg", null);
        writer.addAnnotation(PdfAnnotation.createScreen(writer,
                new Rectangle(200f, 700f, 400f, 800f), "Fox and Dog", fs,
                "video/mpeg", true));
        // step 5
        document.close();
    }
    
    /**
     * Main method.
     *
     * @param    args    no arguments needed
     * @throws DocumentException 
     * @throws IOException 
     * @throws DocumentException 
     * @throws IOException
     */
    public static void main(String[] args) throws IOException, DocumentException {
        new MovieAnnotation().createPdf(RESULT);
    }
}
Pdf3D.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
/*
 * 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 part4.chapter16;
 
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
 
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PdfAnnotation;
import com.itextpdf.text.pdf.PdfAppearance;
import com.itextpdf.text.pdf.PdfArray;
import com.itextpdf.text.pdf.PdfDictionary;
import com.itextpdf.text.pdf.PdfIndirectObject;
import com.itextpdf.text.pdf.PdfName;
import com.itextpdf.text.pdf.PdfNumber;
import com.itextpdf.text.pdf.PdfStream;
import com.itextpdf.text.pdf.PdfString;
import com.itextpdf.text.pdf.PdfWriter;
 
public class Pdf3D {
 
    /** The resulting PDF file. */
    public static String RESULT = "results/part4/chapter16/pdf3d.pdf";
    /** The path to a 3D file. */
    public static String RESOURCE = "resources/img/teapot.u3d";
 
    /**
     * Main method.
     *
     * @param    args    no arguments needed
     * @throws DocumentException 
     * @throws IOException
     */
    public static void main(String[] args) throws IOException, DocumentException {
        new Pdf3D().createPdf(RESULT);
    }
 
    /**
     * Creates the PDF.
     * @param  filename   the path to the resulting PDF file
     * @throws DocumentException
     * @throws IOException
     */
    public void createPdf(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
        Rectangle rect = new Rectangle(100, 400, 500, 800);
        rect.setBorder(Rectangle.BOX);
        rect.setBorderWidth(0.5f);
        rect.setBorderColor(new BaseColor(0xFF, 0x00, 0x00));
        document.add(rect);
            
        PdfStream stream3D = new PdfStream(new FileInputStream(RESOURCE), writer);
        stream3D.put(PdfName.TYPE, new PdfName("3D"));
        stream3D.put(PdfName.SUBTYPE, new PdfName("U3D"));
        stream3D.flateCompress();
        PdfIndirectObject streamObject = writer.addToBody(stream3D);
        stream3D.writeLength();
            
        PdfDictionary dict3D = new PdfDictionary();
        dict3D.put(PdfName.TYPE, new PdfName("3DView"));
        dict3D.put(new PdfName("XN"), new PdfString("Default"));
        dict3D.put(new PdfName("IN"), new PdfString("Unnamed"));
        dict3D.put(new PdfName("MS"), PdfName.M);
        dict3D.put(new PdfName("C2W"),
            new PdfArray(new float[] { 1, 0, 0, 0, 0, -1, 0, 1, 0, 3, -235, 28 } ));
        dict3D.put(PdfName.CO, new PdfNumber(235));
 
        PdfIndirectObject dictObject = writer.addToBody(dict3D); 
            
        PdfAnnotation annot = new PdfAnnotation(writer, rect);
        annot.put(PdfName.CONTENTS, new PdfString("3D Model"));
        annot.put(PdfName.SUBTYPE, new PdfName("3D"));
        annot.put(PdfName.TYPE, PdfName.ANNOT);
        annot.put(new PdfName("3DD"), streamObject.getIndirectReference());
        annot.put(new PdfName("3DV"), dictObject.getIndirectReference());
        PdfAppearance ap = writer.getDirectContent().createAppearance(rect.getWidth(), rect.getHeight());
        annot.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, ap);
        annot.setPage();
 
        writer.addAnnotation(annot);
        // step 5
        document.close();
    }
}
FestivalCalendar1.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
/*
 * 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 part4.chapter16;
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.PdfAnnotation;
import com.itextpdf.text.pdf.PdfDeveloperExtension;
import com.itextpdf.text.pdf.PdfFileSpecification;
import com.itextpdf.text.pdf.PdfIndirectReference;
import com.itextpdf.text.pdf.PdfName;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.richmedia.RichMediaActivation;
import com.itextpdf.text.pdf.richmedia.RichMediaAnnotation;
import com.itextpdf.text.pdf.richmedia.RichMediaConfiguration;
import com.itextpdf.text.pdf.richmedia.RichMediaInstance;
import com.itextpdf.text.pdf.richmedia.RichMediaParams;
 
 
public class FestivalCalendar1 {
    
    /** The resulting PDF file. */
    public static final String RESULT = "results/part4/chapter16/festival_calendar1.pdf";
    /** The path to a Flash application. */
    public static final String RESOURCE = "resources/swf/FestivalCalendar1.swf";
 
    /**
     * Main method.
     *
     * @param    args    no arguments needed
     * @throws DocumentException 
     * @throws IOException
     */
    public static void main(String[] args) throws IOException, DocumentException {
        // step 1
        Document document = new Document();
        // step 2
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(RESULT));
        writer.setPdfVersion(PdfWriter.PDF_VERSION_1_7);
        writer.addDeveloperExtension(PdfDeveloperExtension.ADOBE_1_7_EXTENSIONLEVEL3);
        // step 3
        document.open();
        // step 4
        // we prepare a RichMediaAnnotation
        RichMediaAnnotation richMedia = new RichMediaAnnotation(writer, new Rectangle(36, 400, 559,806));
        // we embed the swf file
        PdfFileSpecification fs
            = PdfFileSpecification.fileEmbedded(writer, RESOURCE, "FestivalCalendar1.swf", null);
        // we declare the swf file as an asset
        PdfIndirectReference asset = richMedia.addAsset("FestivalCalendar1.swf", fs);
        // we create a configuration
        RichMediaConfiguration configuration = new RichMediaConfiguration(PdfName.FLASH);
        RichMediaInstance instance = new RichMediaInstance(PdfName.FLASH);
        RichMediaParams flashVars = new RichMediaParams();
        String vars = new String("&day=2011-10-13");
        flashVars.setFlashVars(vars);
        instance.setParams(flashVars);
        instance.setAsset(asset);
        configuration.addInstance(instance);
        // we add the configuration to the annotation
        PdfIndirectReference configurationRef = richMedia.addConfiguration(configuration);
        // activation of the rich media
        RichMediaActivation activation = new RichMediaActivation();
        activation.setConfiguration(configurationRef);
        richMedia.setActivation(activation);
        // we add the annotation
        PdfAnnotation richMediaAnnotation = richMedia.createAnnotation();
        richMediaAnnotation.setFlags(PdfAnnotation.FLAGS_PRINT);
        writer.addAnnotation(richMediaAnnotation);
        // step 5
        document.close();
    }
}
FestivalCalendar2.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
/*
 * 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 part4.chapter16;
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.Utilities;
import com.itextpdf.text.pdf.GrayColor;
import com.itextpdf.text.pdf.PdfAnnotation;
import com.itextpdf.text.pdf.PdfBorderDictionary;
import com.itextpdf.text.pdf.PdfDeveloperExtension;
import com.itextpdf.text.pdf.PdfFileSpecification;
import com.itextpdf.text.pdf.PdfFormField;
import com.itextpdf.text.pdf.PdfIndirectReference;
import com.itextpdf.text.pdf.PdfName;
import com.itextpdf.text.pdf.PdfString;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.PushbuttonField;
import com.itextpdf.text.pdf.TextField;
import com.itextpdf.text.pdf.richmedia.RichMediaActivation;
import com.itextpdf.text.pdf.richmedia.RichMediaAnnotation;
import com.itextpdf.text.pdf.richmedia.RichMediaCommand;
import com.itextpdf.text.pdf.richmedia.RichMediaConfiguration;
import com.itextpdf.text.pdf.richmedia.RichMediaExecuteAction;
import com.itextpdf.text.pdf.richmedia.RichMediaInstance;
 
 
public class FestivalCalendar2 {
 
    /** The resulting PDF file. */
    public static final String RESULT = "results/part4/chapter16/festival_calendar2.pdf";
    /** The path to a Flash application. */
    public static final String RESOURCE = "resources/swf/FestivalCalendar2.swf";
    /** The path to a JavaScript file. */
    public static final String JS = "resources/js/show_date.js";
 
    /**
     * Main method.
     *
     * @param    args    no arguments needed
     * @throws DocumentException 
     * @throws IOException
     */
    public static void main(String[] args) throws IOException, DocumentException {
        // step 1
        Document document = new Document();
        // step 2
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(RESULT));
        writer.setPdfVersion(PdfWriter.PDF_VERSION_1_7);
        writer.addDeveloperExtension(PdfDeveloperExtension.ADOBE_1_7_EXTENSIONLEVEL3);
        // step 3
        document.open();
        // step 4
        writer.addJavaScript(Utilities.readFileToString(JS));
        // we prepare a RichMediaAnnotation
        RichMediaAnnotation richMedia = new RichMediaAnnotation(writer, new Rectangle(36, 560, 561, 760));
        // we embed the swf file
        PdfFileSpecification fs
            = PdfFileSpecification.fileEmbedded(writer, RESOURCE, "FestivalCalendar2.swf", null);
        // we declare the swf file as an asset
        PdfIndirectReference asset = richMedia.addAsset("FestivalCalendar2.swf", fs);
        // we create a configuration
        RichMediaConfiguration configuration = new RichMediaConfiguration(PdfName.FLASH);
        RichMediaInstance instance = new RichMediaInstance(PdfName.FLASH);
        instance.setAsset(asset);
        configuration.addInstance(instance);
        // we add the configuration to the annotation
        PdfIndirectReference configurationRef = richMedia.addConfiguration(configuration);
        // activation of the rich media
        RichMediaActivation activation = new RichMediaActivation();
        activation.setConfiguration(configurationRef);
        richMedia.setActivation(activation);
        // we add the annotation
        PdfAnnotation richMediaAnnotation = richMedia.createAnnotation();
        richMediaAnnotation.setFlags(PdfAnnotation.FLAGS_PRINT);
        writer.addAnnotation(richMediaAnnotation);
        
        String[] days = new String[]{"2011-10-12", "2011-10-13", "2011-10-14", "2011-10-15",
                "2011-10-16", "2011-10-17", "2011-10-18", "2011-10-19"};
        for (int i = 0; i < days.length; i++) {
            Rectangle rect = new Rectangle(36 + (65 * i), 765, 100 + (65 * i), 780);
            PushbuttonField button = new PushbuttonField(writer, rect, "button" + i);
            button.setBackgroundColor(new GrayColor(0.75f));
            button.setBorderStyle(PdfBorderDictionary.STYLE_BEVELED);
            button.setTextColor(GrayColor.GRAYBLACK);
            button.setFontSize(12);
            button.setText(days[i]);
            button.setLayout(PushbuttonField.LAYOUT_ICON_LEFT_LABEL_RIGHT);
            button.setScaleIcon(PushbuttonField.SCALE_ICON_ALWAYS);
            button.setProportionalIcon(true);
            button.setIconHorizontalAdjustment(0);
            PdfFormField field = button.getField();
            RichMediaCommand command = new RichMediaCommand(new PdfString("getDateInfo"));
            command.setArguments(new PdfString(days[i]));
            RichMediaExecuteAction action
                = new RichMediaExecuteAction(richMediaAnnotation.getIndirectReference(), command);
            field.setAction(action);
            writer.addAnnotation(field);
        }
        TextField text = new TextField(writer, new Rectangle(36, 785, 559, 806), "date");
        text.setOptions(TextField.READ_ONLY);
        writer.addAnnotation(text.getTextField());
        // step 5
        document.close();
    }
}
SpecialId.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.IO;
using System.Collections.Generic;
using Ionic.Zip;
using iTextSharp.text;
using iTextSharp.text.pdf;
 
namespace kuujinbo.iTextInAction2Ed.Chapter16 {
  public class SpecialId : IWriter {
// ===========================================================================
    /** The resulting PDF file. */
    public const String RESULT = "special_id.pdf";
    /** An image file. */
    public readonly String RESOURCE = Path.Combine(
      Utility.ResourceImage, "bruno.jpg"
    );    
// ---------------------------------------------------------------------------    
    public void Write(Stream stream) {
      using (ZipFile zip = new ZipFile()) {
        zip.AddFile(RESOURCE, "");
        zip.AddEntry(RESULT, new SpecialId().CreatePdf());       
        zip.Save(stream);             
      }
    } 
// ---------------------------------------------------------------------------    
    /**
     * Creates a PDF document.
     */
    public byte[] CreatePdf() {
      using (MemoryStream ms = new MemoryStream()) {
        using (Document document = new Document(new Rectangle(400, 300))) {
          PdfWriter writer = PdfWriter.GetInstance(document, ms);
          document.Open();
          Image img = Image.GetInstance(
            Path.Combine(Utility.ResourceImage, "bruno.jpg"
          ));
          img.ScaleAbsolute(400, 300);
          img.SetAbsolutePosition(0, 0);
          PdfImage pi = new PdfImage(img, "", null);
          pi.Put(new PdfName("ITXT_SpecialId"), new PdfName("123456789"));
          PdfIndirectObject pio = writer.AddToBody(pi);
          img.DirectReference = pio.IndirectReference;
          document.Add(img);
        }
        return ms.ToArray();
      }
    }
// ===========================================================================
  }
}
ResizeImage.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
/*
 * 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.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Collections.Generic;
using Ionic.Zip;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.parser;
 
namespace kuujinbo.iTextInAction2Ed.Chapter16 {
  public class ResizeImage : IWriter {
// ===========================================================================
    /** The resulting PDF file. */
    public const String RESULT = "resized_image.pdf";
    /** The multiplication factor for the image. */
    public const float FACTOR = 0.5f;
// ---------------------------------------------------------------------------    
    public void Write(Stream stream) {
      using (ZipFile zip = new ZipFile()) {
        SpecialId s = new SpecialId();
        byte[] pdf = s.CreatePdf();
        zip.AddEntry(Utility.ResultFileName(s.ToString() + ".pdf"), pdf);       
        zip.AddEntry(RESULT, new ResizeImage().ManipulatePdf(pdf));       
        zip.Save(stream);             
      }
    } 
// ---------------------------------------------------------------------------
    /**
     * Manipulates a PDF file src with the byte array as result
     */    
    public byte[] ManipulatePdf(byte[] pdf) {
      PdfName key = new PdfName("ITXT_SpecialId");
      PdfName value = new PdfName("123456789");
      // Read the file
      PdfReader reader = new PdfReader(pdf);
      int n = reader.XrefSize;
      PdfObject pdfObject;
      PRStream prStream;
      // Look for image and manipulate image prStream
      for (int i = 0; i < n; i++) {
        pdfObject = reader.GetPdfObject(i);
        if (pdfObject == null || !pdfObject.IsStream()) continue;
        
        prStream = (PRStream) pdfObject;
        byte[] imageBytes;
        if (value.Equals(prStream.Get(key))) {
          PdfImageObject image = new PdfImageObject(prStream);
          using (System.Drawing.Image original = image.GetDrawingImage()) {
            if (original == null) continue;
            int width = (int)(original.Width * FACTOR);
            int height = (int)(original.Height * FACTOR);
            
            using (System.Drawing.Image thumb = new Bitmap(width, height) ) {
              using ( Graphics graphic = Graphics.FromImage(thumb) ) {
                graphic.DrawImage(original, 0, 0, width, height);
                using (MemoryStream ms = new MemoryStream()) {
                  thumb.Save(ms, ImageFormat.Jpeg);
                  imageBytes = ms.ToArray();
                }
              }
            }
            prStream.Clear();
            prStream.SetData(imageBytes, false, PRStream.NO_COMPRESSION);
            prStream.Put(PdfName.TYPE, PdfName.XOBJECT);
            prStream.Put(PdfName.SUBTYPE, PdfName.IMAGE);
            prStream.Put(key, value);
            prStream.Put(PdfName.FILTER, PdfName.DCTDECODE);
            prStream.Put(PdfName.WIDTH, new PdfNumber(width));
            prStream.Put(PdfName.HEIGHT, new PdfNumber(height));
            prStream.Put(PdfName.BITSPERCOMPONENT, new PdfNumber(8));
            prStream.Put(PdfName.COLORSPACE, PdfName.DEVICERGB);            
          }
        }
      }
      // Save altered PDF
      using (MemoryStream ms = new MemoryStream()) {
        using (PdfStamper stamper = new PdfStamper(reader, ms)) {
        }
        return ms.ToArray();
      }
    }
// ===========================================================================
  }
}
ListUsedFonts.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
/*
 * 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 System.Linq;
using System.Text;
using Ionic.Zip;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.parser;
using kuujinbo.iTextInAction2Ed.Chapter11;
 
namespace kuujinbo.iTextInAction2Ed.Chapter16 {
  public class ListUsedFonts : IWriter {
// ===========================================================================
    /** The resulting PDF file. */
    public const String RESULT = "fonts.txt";
// ---------------------------------------------------------------------------    
    public void Write(Stream stream) {
      using (ZipFile zip = new ZipFile()) {
        FontTypes f = new FontTypes();
        byte[] pdf = Utility.PdfBytes(f);
        zip.AddEntry(Utility.ResultFileName(f.ToString() + ".pdf"), pdf);
        IEnumerable<String> set1 = from m 
          in new ListUsedFonts().ListFonts(pdf)
          orderby m select m;
        StringBuilder sb = new StringBuilder();
/*
 * i don't have c:/windows/fonts/ARBLI__.TTF on my system;
 * if you compare to Java example __THIS__ result file will have
 * one __LESS__ font listed!
 */
        foreach (String fontname in set1) {
          sb.AppendLine(fontname);
        }        
        zip.AddEntry(RESULT, sb.ToString());       
        zip.Save(stream);
      }
    }
// ---------------------------------------------------------------------------    
    /**
     * Creates a HashSet containing information about the fonts in the src PDF file.
     * @param src the PDF file
     * 
     * HashSet only available in .NET >= 3.5
     */
    public HashSet<String> ListFonts(byte[] src) {
      HashSet<String> set = new HashSet<String>();
      PdfReader reader = new PdfReader(src);
      PdfDictionary resources;
      for (int k = 1; k <= reader.NumberOfPages; ++k) {
        resources = reader.GetPageN(k).GetAsDict(PdfName.RESOURCES);
        ProcessResource(set, resources);
      }
      return set;
    }
// ---------------------------------------------------------------------------    
    /**
     * Extracts the font names from page or XObject resources.
     * @param set the HashSet with the font names
     * @param resources the resources dictionary
     */
    public void ProcessResource(HashSet<String> set, PdfDictionary resource) {
        if (resource == null) return;
        
        PdfDictionary xobjects = resource.GetAsDict(PdfName.XOBJECT);
        if (xobjects != null) {
          foreach (PdfName key in xobjects.Keys) {
            ProcessResource(set, xobjects.GetAsDict(key));
          }
        }
        PdfDictionary fonts = resource.GetAsDict(PdfName.FONT);
        if (fonts == null) return;
        
        PdfDictionary font;
        foreach (PdfName key in fonts.Keys) {
          font = fonts.GetAsDict(key);
          String name = font.GetAsName(PdfName.BASEFONT).ToString();
          if (name.Length > 8 && name.Substring(7, 1) == "+") {
            name = String.Format(
              "{0} subset ({1})", 
              name.Substring(8), name.Substring(1, 7)
            );
          }
          else {
              name = name.Substring(1);
              PdfDictionary desc = font.GetAsDict(PdfName.FONTDESCRIPTOR);
              if (desc == null) {
                name += " nofontdescriptor";
              }
              else if (desc.Get(PdfName.FONTFILE) != null) {
                name += " (Type 1) embedded";
              }
              else if (desc.Get(PdfName.FONTFILE2) != null) {
                name += " (TrueType) embedded";
              }
              else if (desc.Get(PdfName.FONTFILE3) != null) {
                name += " (" + font.GetAsName(PdfName.SUBTYPE).ToString().Substring(1) + ") embedded";
              }
          }
          set.Add(name);
        }
    }
// ===========================================================================  
  }
}
EmbedFontPostFacto.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
/*
 * 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.Chapter16 {
  public class EmbedFontPostFacto : IWriter {
// ===========================================================================
    /** The first resulting PDF file. */
    public const String RESULT1 = "without_font.pdf";
    /** The second resulting PDF file. */
    public const String RESULT2 = "with_font.pdf";
    /** A special font. */
    public readonly String FONT = Path.Combine(
      Utility.ResourceFonts, "wds011402.ttf"
    );     
    /** The name of the special font. */
    public const String FONTNAME = "WaltDisneyScriptv4.1";
// ---------------------------------------------------------------------------    
    public void Write(Stream stream) {
      using (ZipFile zip = new ZipFile()) {
        EmbedFontPostFacto example = new EmbedFontPostFacto();
        byte[] pdf = example.CreatePdf();
        zip.AddEntry(RESULT1, pdf);       
        zip.AddEntry(RESULT2, example.ManipulatePdf(pdf));       
        zip.Save(stream);             
      }
    }     
// --------------------------------------------------------------------------- 
    /**
     * Creates a PDF document.
     */
    public byte[] CreatePdf() {
      using (MemoryStream ms = new MemoryStream()) {
        // step 1
        using (Document document = new Document()) {    
          // step 2
          PdfWriter.GetInstance(document, ms);
          // step 3
          document.Open();
          // step 4:
          Font font = new Font(
            BaseFont.CreateFont(FONT, "", BaseFont.NOT_EMBEDDED), 60
          );
          document.Add(new Paragraph("iText in Action", font));
        }
        return ms.ToArray();
      }
    }
// ---------------------------------------------------------------------------     
    /**
     * Manipulates a PDF file src with the file dest as result
     * @param src the original PDF
     */
    public byte[] ManipulatePdf(byte[] src) {
      // the font file
      byte[] fontfile = null;
      using (FileStream fs = new FileStream(
        FONT, FileMode.Open, FileAccess.Read)) 
      {
        fontfile = new byte[fs.Length];
        fs.Read(fontfile, 0, (int) fs.Length);
      }
      // create a new stream for the font file
      PdfStream stream = new PdfStream(fontfile);
      stream.FlateCompress();
      stream.Put(PdfName.LENGTH1, new PdfNumber(fontfile.Length));
      // create a reader object
      PdfReader reader = new PdfReader(src);
      int n = reader.XrefSize;
      PdfDictionary font;
      using (MemoryStream ms = new MemoryStream()) {      
        using (PdfStamper stamper = new PdfStamper(reader, ms)) {
          PdfName fontname = new PdfName(FONTNAME);
          for (int i = 0; i < n; i++) {
            PdfObject objectPdf = reader.GetPdfObject(i);
            if (objectPdf == null || !objectPdf.IsDictionary()) {
              continue;
            }
            font = (PdfDictionary)objectPdf;
            if (PdfName.FONTDESCRIPTOR.Equals(font.Get(PdfName.TYPE))
                && fontname.Equals(font.Get(PdfName.FONTNAME))) 
            {
              PdfIndirectObject objref = stamper.Writer.AddToBody(stream);
              font.Put(PdfName.FONTFILE2, objref.IndirectReference);
            }
          }
        }
        return ms.ToArray();
      }
    } 
// ===========================================================================    
  }
}
KubrickDvds.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.Linq;
using System.Collections.Generic;
using Ionic.Zip;
using iTextSharp.text;
using iTextSharp.text.pdf;
using kuujinbo.iTextInAction2Ed.Intro_1_2;
 
namespace kuujinbo.iTextInAction2Ed.Chapter16 {
  public class KubrickDvds : IWriter {
// ===========================================================================
    /** The filename of the resulting PDF. */
    public const String RESULT = "kubrick_dvds.pdf";
// ---------------------------------------------------------------------------
    public void Write(Stream stream) {
      using (ZipFile zip = new ZipFile()) {
        KubrickDvds kubrick = new KubrickDvds();
        byte[] ePdf = kubrick.CreatePdf();
        zip.AddEntry(RESULT, ePdf);
        kubrick.ExtractAttachments(ePdf, zip);
        zip.Save(stream);             
      }
    }
// ---------------------------------------------------------------------------    
    /**
     * Extracts attachments from an existing PDF.
     * @param src the path to the existing PDF
     * @param zip the ZipFile object to add the extracted images
     */
    public void ExtractAttachments(byte[] src, ZipFile zip) {
      PdfReader reader = new PdfReader(src);
      for (int i = 1; i <= reader.NumberOfPages; i++) {
        PdfArray array = reader.GetPageN(i).GetAsArray(PdfName.ANNOTS);
        if (array == null) continue;
        for (int j = 0; j < array.Size; j++) {
          PdfDictionary annot = array.GetAsDict(j);
          if (PdfName.FILEATTACHMENT.Equals(
              annot.GetAsName(PdfName.SUBTYPE)))
          {
            PdfDictionary fs = annot.GetAsDict(PdfName.FS);
            PdfDictionary refs = fs.GetAsDict(PdfName.EF);
            foreach (PdfName name in refs.Keys) {
              zip.AddEntry(
                fs.GetAsString(name).ToString(), 
                PdfReader.GetStreamBytes((PRStream)refs.GetAsStream(name))
              );
            }
          }
        }
      }
    }
// ---------------------------------------------------------------------------
    /**
     * Creates the PDF.
     * @return the bytes of a PDF file.
     */
    public byte[] CreatePdf() {
      using (MemoryStream ms = new MemoryStream()) {
        using (Document document = new Document()) {
          PdfWriter writer = PdfWriter.GetInstance(document, ms);
          document.Open();
          document.Add(new Paragraph(
            "This is a list of Kubrick movies available in DVD stores."
          ));
          IEnumerable<Movie> movies = PojoFactory.GetMovies(1)
            .Concat(PojoFactory.GetMovies(4))
          ;          
          List list = new List();
          string RESOURCE = Utility.ResourcePosters;
          foreach (Movie movie in movies) {
            PdfAnnotation annot = PdfAnnotation.CreateFileAttachment(
              writer, null, 
              movie.GetMovieTitle(false), null,
              Path.Combine(RESOURCE, movie.Imdb + ".jpg"),
              string.Format("{0}.jpg", movie.Imdb)              
            );
            ListItem item = new ListItem(movie.GetMovieTitle(false));
            item.Add("\u00a0\u00a0");
            Chunk chunk = new Chunk("\u00a0\u00a0\u00a0\u00a0");
            chunk.SetAnnotation(annot);
            item.Add(chunk);
            list.Add(item);
          }
          document.Add(list);
        }
        return ms.ToArray();
      }
    }    
// ===========================================================================
    }
}
KubrickDocumentary.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
/*
 * 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 System.Linq;
using System.Text;
using Ionic.Zip;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.xml;
using kuujinbo.iTextInAction2Ed.Intro_1_2;
 
namespace kuujinbo.iTextInAction2Ed.Chapter16 {
  public class KubrickDocumentary : IWriter {
// ===========================================================================
    /** The filename of the resulting PDF. */
    public const String RESULT = "kubrick_documentary.pdf";
// ---------------------------------------------------------------------------
    public void Write(Stream stream) {
      using (ZipFile zip = new ZipFile()) {
        KubrickDocumentary kubrick = new KubrickDocumentary();
        byte[] ePdf = kubrick.CreatePdf();
        zip.AddEntry(RESULT, ePdf);
        kubrick.ExtractDocLevelAttachments(ePdf, zip);
        zip.Save(stream);             
      }
    }
// ---------------------------------------------------------------------------
    /**
     * Creates the PDF.
     * @return the bytes of a PDF file.
     */
    public byte[] CreatePdf() {
      IEnumerable<Movie> movies = PojoFactory.GetMovies(1);
      using (MemoryStream ms = new MemoryStream()) {
        using (Document document = new Document()) {
          PdfWriter writer = PdfWriter.GetInstance(document, ms);
          document.Open();
          document.Add(new Paragraph(
            "'Stanley Kubrick: A Life in Pictures'"
            + " is a documentary about Stanley Kubrick and his films:"
          ));
          StringBuilder sb = new StringBuilder();
          sb.AppendLine("<movies>");
          List list = new List(List.UNORDERED, 20);
          foreach (Movie movie in movies) {
            sb.AppendLine("<movie>");
            sb.AppendLine(String.Format(
              "<title>{0}</title>",
              XMLUtil.EscapeXML(movie.MovieTitle, true)
            ));
            sb.AppendLine(String.Format("<year>{0}</year>", movie.Year));
            sb.AppendLine(String.Format(
              "<duration>{0}</duration>", movie.Duration
            ));
            sb.AppendLine("</movie>");
            ListItem item = new ListItem(movie.MovieTitle);
            list.Add(item);
          }
          document.Add(list);
          sb.Append("</movies>");
          PdfFileSpecification fs = PdfFileSpecification.FileEmbedded(
            writer, null, "kubrick.xml", Encoding.UTF8.GetBytes(sb.ToString())
            //txt.toByteArray()
          );
          writer.AddFileAttachment(fs);
        }
        return ms.ToArray();
      }
    }
// ---------------------------------------------------------------------------
    /**
     * Extracts document level attachments
     * @param PDF from which document level attachments will be extracted
     * @param zip the ZipFile object to add the extracted images
     */
    public void ExtractDocLevelAttachments(byte[] pdf, ZipFile zip) {
      PdfReader reader = new PdfReader(pdf);
      PdfDictionary root = reader.Catalog;
      PdfDictionary documentnames = root.GetAsDict(PdfName.NAMES);
      PdfDictionary embeddedfiles = 
          documentnames.GetAsDict(PdfName.EMBEDDEDFILES);
      PdfArray filespecs = embeddedfiles.GetAsArray(PdfName.NAMES);
      for (int i = 0; i < filespecs.Size; ) {
        filespecs.GetAsString(i++);
        PdfDictionary filespec = filespecs.GetAsDict(i++);
        PdfDictionary refs = filespec.GetAsDict(PdfName.EF);
        foreach (PdfName key in refs.Keys) {
          PRStream stream = (PRStream) PdfReader.GetPdfObject(
            refs.GetAsIndirectObject(key)
          );
          zip.AddEntry(
            filespec.GetAsString(key).ToString(), 
            PdfReader.GetStreamBytes(stream)
          );
        }
      }
    }
// ===========================================================================
    }
}
KubrickBox.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
/*
 * 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 System.Linq;
using System.Text;
using Ionic.Zip;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.collection;
using kuujinbo.iTextInAction2Ed.Intro_1_2;
 
namespace kuujinbo.iTextInAction2Ed.Chapter16 {
  public class KubrickBox : IWriter {
// ===========================================================================
    /** The resulting PDF. */
    public const String RESULT = "kubrick_box.pdf";
    /** The path to an image used in the example. */
    public readonly String IMG_BOX =  Path.Combine(
      Utility.ResourceImage, "kubrick_box.jpg"
    );
    /** Path to the resources. */
    public readonly String RESOURCE =  Path.Combine(
      Utility.ResourcePosters, "{0}.jpg"
    );    
    /** The relative widths of the PdfPTable columns. */
    public readonly float[] WIDTHS = { 1 , 7 };
// --------------------------------------------------------------------------- 
    public void Write(Stream stream) {
      // step 1
      using (Document document = new Document()) {
        // step 2
        PdfWriter writer = PdfWriter.GetInstance(document, stream);
        // step 3
        document.Open();
        // step 4
        Image img = Image.GetInstance(IMG_BOX);
        document.Add(img);
        List list = new List(List.UNORDERED, 20);
        PdfDestination dest = new PdfDestination(PdfDestination.FIT);
        dest.AddFirst(new PdfNumber(1));
        IEnumerable<Movie> box = PojoFactory.GetMovies(1)
          .Concat(PojoFactory.GetMovies(4))
        ;
        foreach (Movie movie in box) {
          if (movie.Year > 1960) {
            PdfFileSpecification fs = PdfFileSpecification.FileEmbedded(
              writer, null,
              String.Format("kubrick_{0}.pdf", movie.Imdb),
              CreateMoviePage(movie)
            );
            fs.AddDescription(movie.Title, false);
            writer.AddFileAttachment(fs);
            ListItem item = new ListItem(movie.MovieTitle);
            PdfTargetDictionary target = new PdfTargetDictionary(true);
            target.EmbeddedFileName = movie.Title;
            PdfAction action = PdfAction.GotoEmbedded(null, target, dest, true);
            Chunk chunk = new Chunk(" (see info)");
            chunk.SetAction(action);
            item.Add(chunk);
            list.Add(item);
          }
        }
        document.Add(list);
      }
    }
// --------------------------------------------------------------------------- 
    /**
     * Creates the PDF.
     * @return the bytes of a PDF file.
     */
    public byte[] CreateMoviePage(Movie movie) {
      using (MemoryStream ms = new MemoryStream()) {
        // step 1
        using (Document document = new Document()) {
          // step 2
          PdfWriter.GetInstance(document, ms);
          // step 3
          document.Open();
          // step 4
          Paragraph p = new Paragraph(
            movie.MovieTitle,
            FontFactory.GetFont(
              BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.NOT_EMBEDDED, 16
            )
          );
          document.Add(p);
          document.Add(Chunk.NEWLINE);
          PdfPTable table = new PdfPTable(WIDTHS);
          table.AddCell(Image.GetInstance(
            String.Format(RESOURCE, movie.Imdb)
          ));
          PdfPCell cell = new PdfPCell();
          cell.AddElement(new Paragraph("Year: " + movie.Year.ToString()));
          cell.AddElement(new Paragraph("Duration: " + movie.Duration.ToString()));
          table.AddCell(cell);
          document.Add(table);
          PdfDestination dest = new PdfDestination(PdfDestination.FIT);
          dest.AddFirst(new PdfNumber(1));
          PdfTargetDictionary target = new PdfTargetDictionary(false);
          Chunk chunk = new Chunk("Go to original document");
          PdfAction action = PdfAction.GotoEmbedded(null, target, dest, false);
          chunk.SetAction(action);
          document.Add(chunk);
        }
        return ms.ToArray();
      }
    }
    
// ===========================================================================
  }
}
KubrickMovies.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
154
155
156
157
158
159
160
161
/*
 * 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 System.Linq;
using System.Text;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.collection;
using kuujinbo.iTextInAction2Ed.Intro_1_2;
 
namespace kuujinbo.iTextInAction2Ed.Chapter16 {
  public class KubrickMovies : IWriter {
// ===========================================================================
    /** Path to the resources. */
    public readonly String RESOURCE =  Path.Combine(
      Utility.ResourcePosters, "{0}.jpg"
    );    
    /** The relative widths of the PdfPTable columns. */
    public readonly float[] WIDTHS = { 1 , 7 };
    /** The filename of the PDF */
    public const String FILENAME = "kubrick_movies.pdf";    
// --------------------------------------------------------------------------- 
    public void Write(Stream stream) {
      // step 1
      using (Document document = new Document()) {
        // step 2
        PdfWriter writer = PdfWriter.GetInstance(document, stream);
        // step 3
        document.Open();
        // step 4
        document.Add(new Paragraph(
          "This document contains a collection of PDFs,"
          + " one per Stanley Kubrick movie."
        ));
        
        PdfCollection collection = new PdfCollection(PdfCollection.DETAILS);
        PdfCollectionSchema schema = _collectionSchema(); 
        collection.Schema = schema;
        PdfCollectionSort sort = new PdfCollectionSort("YEAR");
        sort.SetSortOrder(false);
        collection.Sort = sort;
        collection.InitialDocument = "Eyes Wide Shut";
        writer.Collection = collection;
        
        PdfCollectionItem item;
        IEnumerable<Movie> movies = PojoFactory.GetMovies(1);
        foreach (Movie movie in movies) {
          PdfFileSpecification fs = PdfFileSpecification.FileEmbedded(
            writer, null,
            String.Format("kubrick_{0}.pdf", movie.Imdb),
            CreateMoviePage(movie)
          );
          fs.AddDescription(movie.Title, false);
 
          item = new PdfCollectionItem(schema);
          item.AddItem("TITLE", movie.GetMovieTitle(false));
          if (movie.GetMovieTitle(true) != null) {
            item.SetPrefix("TITLE", movie.GetMovieTitle(true));
          }
          item.AddItem("DURATION", movie.Duration.ToString());
          item.AddItem("YEAR", movie.Year.ToString());
          fs.AddCollectionItem(item);
          writer.AddFileAttachment(fs);
        }
      }
    }
// ---------------------------------------------------------------------------     
    /**
     * Creates a Collection schema that can be used to organize the movies 
     * of Stanley Kubrick in a collection: year, title, duration, DVD 
     * acquisition, filesize (filename is present, but hidden).
     * @return a collection schema
     */
    private PdfCollectionSchema _collectionSchema() {
      PdfCollectionSchema schema = new PdfCollectionSchema();
      PdfCollectionField size = new PdfCollectionField(
        "File size", PdfCollectionField.SIZE
      );
      
      size.Order = 4;
      schema.AddField("SIZE", size);
      
      PdfCollectionField filename = new PdfCollectionField(
        "File name", PdfCollectionField.FILENAME
      );
      filename.Visible = false;
      schema.AddField("FILE", filename);
      
      PdfCollectionField title = new PdfCollectionField(
        "Movie title", PdfCollectionField.TEXT
      );
      title.Order = 1;
      schema.AddField("TITLE", title);
      
      PdfCollectionField duration = new PdfCollectionField(
        "Duration", PdfCollectionField.NUMBER
      );
      duration.Order = 2;
      schema.AddField("DURATION", duration);
      
      PdfCollectionField year = new PdfCollectionField(
        "Year", PdfCollectionField.NUMBER
      );
      year.Order = 0;
      schema.AddField("YEAR", year);
      
      return schema;
    }
// --------------------------------------------------------------------------- 
    /**
     * Creates the PDF.
     * @return the bytes of a PDF file.
     */
    public byte[] CreateMoviePage(Movie movie) {
      using (MemoryStream ms = new MemoryStream()) {
        // step 1
        using (Document document = new Document()) {
          // step 2
          PdfWriter.GetInstance(document, ms);
          // step 3
          document.Open();
          // step 4
          Paragraph p = new Paragraph(
            movie.MovieTitle,
            FontFactory.GetFont(
              BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.NOT_EMBEDDED, 16
            )
          );
          document.Add(p);
          document.Add(Chunk.NEWLINE);
          PdfPTable table = new PdfPTable(WIDTHS);
          table.AddCell(Image.GetInstance(
            String.Format(RESOURCE, movie.Imdb)
          ));
          PdfPCell cell = new PdfPCell();
          cell.AddElement(new Paragraph("Year: " + movie.Year.ToString()));
          cell.AddElement(new Paragraph("Duration: " + movie.Duration.ToString()));
          table.AddCell(cell);
          document.Add(table);
          
          PdfTargetDictionary target = new PdfTargetDictionary(false);
          target.AdditionalPath = new PdfTargetDictionary(false);
          Chunk chunk = new Chunk("Go to original document");
          PdfAction action = PdfAction.GotoEmbedded(
            null, target, new PdfString("movies"), false
          );
          chunk.SetAction(action);
          document.Add(chunk);
        }
        return ms.ToArray();
      }
    }
// ===========================================================================
  }
}
KubrickCollection.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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
/*
 * 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 System.Linq;
using System.Text;
using Ionic.Zip;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.collection;
using kuujinbo.iTextInAction2Ed.Intro_1_2;
 
namespace kuujinbo.iTextInAction2Ed.Chapter16 {
  public class KubrickCollection : IWriter {
// ===========================================================================
    /** An image file used in this example */
    public readonly String IMG_BOX =  Path.Combine(
      Utility.ResourceImage, "kubrick_box.jpg"
    );
    /** An image file used in this example */
    public readonly String IMG_KUBRICK =  Path.Combine(
      Utility.ResourceImage, "kubrick.jpg"
    );       
    /** The name of a field in the collection schema. */
    public const String TYPE_FIELD = "TYPE";
    /** A caption of a field in the collection schema. */
    public const String TYPE_CAPTION = "File type";
    /** The name of a field in the collection schema. */
    public const String FILE_FIELD = "FILE";
    /** A caption of a field in the collection schema. */
    public const String FILE_CAPTION = "File name";
    /** Sort order for the keys in the collection. */
    public String[] KEYS = { TYPE_FIELD, FILE_FIELD };
// --------------------------------------------------------------------------- 
    public void Write(Stream stream) {
      // step 1
      using (Document document = new Document()) {
        // step 2
        PdfWriter writer = PdfWriter.GetInstance(document, stream);
        // step 3
        document.Open();
        
        
        // step 4
        PdfCollection collection = new PdfCollection(PdfCollection.HIDDEN);
        PdfCollectionSchema schema = _collectionSchema();
        collection.Schema = schema;
        PdfCollectionSort sort = new PdfCollectionSort(KEYS);
        collection.Sort = sort;
        writer.Collection = collection;
 
        PdfCollectionItem collectionitem = new PdfCollectionItem(schema);
        PdfFileSpecification fs = PdfFileSpecification.FileEmbedded(
          writer, IMG_KUBRICK, "kubrick.jpg", null
        );
        fs.AddDescription("Stanley Kubrick", false);
        collectionitem.AddItem(TYPE_FIELD, "JPEG");
        fs.AddCollectionItem(collectionitem);
        writer.AddFileAttachment(fs);
        
        Image img = Image.GetInstance(IMG_BOX);
        document.Add(img);
        List list = new List(List.UNORDERED, 20);
        PdfDestination dest = new PdfDestination(PdfDestination.FIT);
        dest.AddFirst(new PdfNumber(1));
        PdfTargetDictionary intermediate;
        PdfTargetDictionary target;
        Chunk chunk;
        ListItem item;
        PdfAction action = null;
 
        IEnumerable<Movie> box = PojoFactory.GetMovies(1)
          .Concat(PojoFactory.GetMovies(4))
        ;
        StringBuilder sb = new StringBuilder();
        foreach (Movie movie in box) {
          if (movie.Year > 1960) {
            sb.AppendLine(String.Format(
              "{0};{1};{2}", movie.MovieTitle, movie.Year, movie.Duration
            ));
            item = new ListItem(movie.MovieTitle);
            if (!"0278736".Equals(movie.Imdb)) {
              target = new PdfTargetDictionary(true);
              target.EmbeddedFileName = movie.Title;
              intermediate = new PdfTargetDictionary(true);
              intermediate.FileAttachmentPage = 1;
              intermediate.FileAttachmentIndex = 1;
              intermediate.AdditionalPath = target;
              action = PdfAction.GotoEmbedded(null, intermediate, dest, true);
              chunk = new Chunk(" (see info)");
              chunk.SetAction(action);
              item.Add(chunk);
            }
            list.Add(item);
          }
        }
        document.Add(list);
        
        fs = PdfFileSpecification.FileEmbedded(
          writer, null, "kubrick.txt", 
          Encoding.UTF8.GetBytes(sb.ToString())
        );
        fs.AddDescription("Kubrick box: the movies", false);
        collectionitem.AddItem(TYPE_FIELD, "TXT");
        fs.AddCollectionItem(collectionitem);
        writer.AddFileAttachment(fs);
 
        PdfPTable table = new PdfPTable(1);
        table.SpacingAfter = 10;
        PdfPCell cell = new PdfPCell(new Phrase("All movies by Kubrick"));
        cell.Border = PdfPCell.NO_BORDER;
        fs = PdfFileSpecification.FileEmbedded(
          writer, null, KubrickMovies.FILENAME, 
          Utility.PdfBytes(new KubrickMovies())
          //new KubrickMovies().createPdf()
        );
        collectionitem.AddItem(TYPE_FIELD, "PDF");
        fs.AddCollectionItem(collectionitem);
        target = new PdfTargetDictionary(true);
        target.FileAttachmentPagename = "movies";
        target.FileAttachmentName = "The movies of Stanley Kubrick";
        cell.CellEvent = new PdfActionEvent(
          writer, PdfAction.GotoEmbedded(null, target, dest, true)
        );
        cell.CellEvent = new FileAttachmentEvent(
          writer, fs, "The movies of Stanley Kubrick"
        );
        cell.CellEvent = new LocalDestinationEvent(writer, "movies");
        table.AddCell(cell);
        writer.AddFileAttachment(fs);
 
        cell = new PdfPCell(new Phrase("Kubrick DVDs"));
        cell.Border = PdfPCell.NO_BORDER;
        fs = PdfFileSpecification.FileEmbedded(
          writer, null, 
          KubrickDvds.RESULT, new KubrickDvds().CreatePdf()
        );
        collectionitem.AddItem(TYPE_FIELD, "PDF");
        fs.AddCollectionItem(collectionitem);
        cell.CellEvent = new FileAttachmentEvent(writer, fs, "Kubrick DVDs");
        table.AddCell(cell);
        writer.AddFileAttachment(fs);
        
        cell = new PdfPCell(new Phrase("Kubrick documentary"));
        cell.Border = PdfPCell.NO_BORDER;
        fs = PdfFileSpecification.FileEmbedded(
          writer, null, 
          KubrickDocumentary.RESULT, new KubrickDocumentary().CreatePdf()
        );
        collectionitem.AddItem(TYPE_FIELD, "PDF");
        fs.AddCollectionItem(collectionitem);
        cell.CellEvent = new FileAttachmentEvent(
          writer, fs, "Kubrick Documentary"
        );
        table.AddCell(cell);
        writer.AddFileAttachment(fs);
 
        document.NewPage();
        document.Add(table);
      }
    }
// ---------------------------------------------------------------------------     
    /**
     * Creates a Collection schema that can be used to organize the movies
     * of Stanley Kubrick in a collection: year, title, duration, 
     * DVD acquisition, filesize (filename is present, but hidden).
     * @return a collection schema
     */
    private PdfCollectionSchema _collectionSchema() {
      PdfCollectionSchema schema = new PdfCollectionSchema();
      
      PdfCollectionField type = new PdfCollectionField(
        TYPE_CAPTION, PdfCollectionField.TEXT
      );
      type.Order = 0;
      schema.AddField(TYPE_FIELD, type);
      
      PdfCollectionField filename = new PdfCollectionField(
        FILE_FIELD, PdfCollectionField.FILENAME
      );
      filename.Order = 1;
      schema.AddField(FILE_FIELD, filename);
      
      return schema;
    }
// ===========================================================================
  }
}
FileAttachmentEvent.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
using System;
using System.Collections.Generic;
using iTextSharp.text;
using iTextSharp.text.pdf;
 
namespace kuujinbo.iTextInAction2Ed.Chapter16 {
  public class FileAttachmentEvent : IPdfPCellEvent {
// ===========================================================================
    /** The writer to which we are going to add the action. */
    protected PdfWriter writer;
    /** The file specification that will be used to create an annotation. */
    protected PdfFileSpecification fs;
    /** The description that comes with the annotation. */
    protected String description;
// ---------------------------------------------------------------------------    
    /**
     * Creates a FileAttachmentEvent.
     * 
     * @param writer      the writer to which the file attachment has to be added.
     * @param fs          the file specification.
     * @param description a description for the file attachment.
     */
    public FileAttachmentEvent(
        PdfWriter writer, PdfFileSpecification fs, String description)
    {
      this.writer = writer;
      this.fs = fs;
      this.description = description;
    }
// ---------------------------------------------------------------------------    
    /**
     * Implementation of the cellLayout method.
     * @see com.itextpdf.text.pdf.PdfPCellEvent#cellLayout(
     * com.itextpdf.text.pdf.PdfPCell, com.itextpdf.text.Rectangle, 
     * com.itextpdf.text.pdf.PdfContentByte[])
     */
    public void CellLayout(
        PdfPCell cell, Rectangle position, PdfContentByte[] canvases) 
    {
      try {
        PdfAnnotation annotation = PdfAnnotation.CreateFileAttachment(
          writer,
          new Rectangle(
            position.Left - 20, position.Top - 15,
            position.Left - 5, position.Top - 5
          ),
          description, fs
        );
        annotation.Name = description;
        writer.AddAnnotation(annotation);
      }
      catch {
        throw;
      }
    }
// ===========================================================================
    }
}
PdfActionEvent.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
using System;
using System.Collections.Generic;
using iTextSharp.text;
using iTextSharp.text.pdf;
 
namespace kuujinbo.iTextInAction2Ed.Chapter16 {
  public class PdfActionEvent : IPdfPCellEvent {
// ===========================================================================
    /** The writer to which we are going to add the action. */
    protected PdfWriter writer;
    /** The action we're going to add. */
    protected PdfAction action;
// ---------------------------------------------------------------------------    
    /** Creates a new Action event. */
    public PdfActionEvent(PdfWriter writer, PdfAction action) {
      this.writer = writer;
      this.action = action;
    }
// ---------------------------------------------------------------------------    
    /** Implementation of the cellLayout method. */
    public void CellLayout(
        PdfPCell cell, Rectangle position, PdfContentByte[] canvases) 
    {
      writer.AddAnnotation(new PdfAnnotation(
        writer,
        position.Left, position.Bottom, position.Right, position.Top,
        action
      ));
    }
// ===========================================================================
    }
}
LocalDestinationEvent.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
using System;
using System.Collections.Generic;
using iTextSharp.text;
using iTextSharp.text.pdf;
 
namespace kuujinbo.iTextInAction2Ed.Chapter16 {
  public class LocalDestinationEvent : IPdfPCellEvent {
// ===========================================================================
    /** The writer to which we are going to add the action. */
    protected PdfWriter writer;
    /** The name of the local destination. */
    protected String name;
// ---------------------------------------------------------------------------    
    /** Creates a new Action event. */
    public LocalDestinationEvent(PdfWriter writer,  String name) {
      this.writer = writer;
      this.name = name;
    }
// ---------------------------------------------------------------------------    
    /** Implementation of the cellLayout method. */
    public void CellLayout(
        PdfPCell cell, Rectangle position, PdfContentByte[] canvases) 
    {
      writer.DirectContent.LocalDestination(
        name,
        new PdfDestination(PdfDestination.FITH, position.Top)
      );
    }
// ===========================================================================
    }
}
MovieAnnotation.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
/*
 * 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 System.Text;
using iTextSharp.text;
using iTextSharp.text.pdf;
 
namespace kuujinbo.iTextInAction2Ed.Chapter16 {
  public class MovieAnnotation : IWriter {
// ===========================================================================
    /** One of the resources. */
    public readonly String RESOURCE = Path.Combine(
      Utility.ResourceImage, "foxdog.mpg"
    );
// ---------------------------------------------------------------------------
    public void Write(Stream stream) {
      // step 1
      using (Document document = new Document()) {
        // step 2
        PdfWriter writer = PdfWriter.GetInstance(document, stream);
        // step 3
        document.Open();
        // step 4
        PdfFileSpecification fs = PdfFileSpecification.FileEmbedded(
          writer, RESOURCE, "foxdog.mpg", null
        );
        writer.AddAnnotation(PdfAnnotation.CreateScreen(
          writer,
          new Rectangle(200f, 700f, 400f, 800f), 
          "Fox and Dog", fs,
          "video/mpeg", true
        ));        
      }
    }
// ===========================================================================
    }
}
Pdf3D.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.Collections.Generic;
using System.IO;
using System.Text;
using iTextSharp.text;
using iTextSharp.text.pdf;
 
namespace kuujinbo.iTextInAction2Ed.Chapter16 {
  public class Pdf3D : IWriter {
// ===========================================================================
    public readonly String RESOURCE = Path.Combine(
      Utility.ResourceImage, "teapot.u3d"
    );
// ---------------------------------------------------------------------------
    public void Write(Stream stream) {
      // step 1
      using (Document document = new Document()) {
        // step 2
        PdfWriter writer = PdfWriter.GetInstance(document, stream);
        // step 3
        document.Open();
        // step 4
        Rectangle rect = new Rectangle(100, 400, 500, 800);
        rect.Border = Rectangle.BOX;
        rect.BorderWidth = 0.5f;
        rect.BorderColor = new BaseColor(0xFF, 0x00, 0x00);
        document.Add(rect);
 
        PdfIndirectObject streamObject = null;
        using (FileStream fs = 
          new FileStream(RESOURCE, FileMode.Open, FileAccess.Read))
        {
          PdfStream stream3D = new PdfStream(fs, writer);
          
          stream3D.Put(PdfName.TYPE, new PdfName("3D"));
          stream3D.Put(PdfName.SUBTYPE, new PdfName("U3D"));
          stream3D.FlateCompress();
          streamObject = writer.AddToBody(stream3D);
          stream3D.WriteLength();
        }
            
        PdfDictionary dict3D = new PdfDictionary();
        dict3D.Put(PdfName.TYPE, new PdfName("3DView"));
        dict3D.Put(new PdfName("XN"), new PdfString("Default"));
        dict3D.Put(new PdfName("IN"), new PdfString("Unnamed"));
        dict3D.Put(new PdfName("MS"), PdfName.M);
        dict3D.Put(
          new PdfName("C2W"),
          new PdfArray(
            new float[] { 1, 0, 0, 0, 0, -1, 0, 1, 0, 3, -235, 28 }
          )
        );
        dict3D.Put(PdfName.CO, new PdfNumber(235));
 
        PdfIndirectObject dictObject = writer.AddToBody(dict3D); 
            
        PdfAnnotation annot = new PdfAnnotation(writer, rect);
        annot.Put(PdfName.CONTENTS, new PdfString("3D Model"));
        annot.Put(PdfName.SUBTYPE, new PdfName("3D"));
        annot.Put(PdfName.TYPE, PdfName.ANNOT);
        annot.Put(new PdfName("3DD"), streamObject.IndirectReference);
        annot.Put(new PdfName("3DV"), dictObject.IndirectReference);
        PdfAppearance ap = writer.DirectContent.CreateAppearance(
          rect.Width, rect.Height
        );
        annot.SetAppearance(PdfAnnotation.APPEARANCE_NORMAL, ap);
        annot.SetPage();
 
        writer.AddAnnotation(annot);      
      }
    }
// ===========================================================================
    }
}
FestivalCalendar1.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
/*
 * 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 System.Linq;
using System.Text;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.richmedia;
 
namespace kuujinbo.iTextInAction2Ed.Chapter16 {
  public class FestivalCalendar1 : IWriter {
// ===========================================================================
    /** The path to a Flash application. */
    public readonly String RESOURCE = Path.Combine(
      Utility.ResourceSwf, "FestivalCalendar1.swf"
    );
// ---------------------------------------------------------------------------
    public void Write(Stream stream) {
      // step 1
      using (Document document = new Document()) {
        // step 2
        PdfWriter writer = PdfWriter.GetInstance(document, stream);
        writer.SetPdfVersion(PdfWriter.PDF_VERSION_1_7);
        writer.AddDeveloperExtension(
          PdfDeveloperExtension.ADOBE_1_7_EXTENSIONLEVEL3
        );
        // step 3
        document.Open();
        // step 4
        // we prepare a RichMediaAnnotation
        RichMediaAnnotation richMedia = new RichMediaAnnotation(
          writer, new Rectangle(36, 400, 559,806)
        );
        // we embed the swf file
        PdfFileSpecification fs = PdfFileSpecification.FileEmbedded(
          writer, RESOURCE, "FestivalCalendar1.swf", null
        );
        // we declare the swf file as an asset
        PdfIndirectReference asset = richMedia.AddAsset(
          "FestivalCalendar1.swf", fs
        );
        // we create a configuration
        RichMediaConfiguration configuration = new RichMediaConfiguration(
          PdfName.FLASH
        );
        RichMediaInstance instance = new RichMediaInstance(PdfName.FLASH);
        RichMediaParams flashVars = new RichMediaParams();
        String vars = "&day=2011-10-13";
        flashVars.FlashVars = vars;
        instance.Params = flashVars;
        instance.Asset = asset;
        configuration.AddInstance(instance);
        // we add the configuration to the annotation
        PdfIndirectReference configurationRef = richMedia.AddConfiguration(
          configuration
        );
        // activation of the rich media
        RichMediaActivation activation = new RichMediaActivation();
        activation.Configuration = configurationRef;
        richMedia.Activation = activation;
        // we add the annotation
        PdfAnnotation richMediaAnnotation = richMedia.CreateAnnotation();
        richMediaAnnotation.Flags = PdfAnnotation.FLAGS_PRINT;
        writer.AddAnnotation(richMediaAnnotation);
      }
    }
// ===========================================================================
    }
}
FestivalCalendar2.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
/*
 * 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 System.Linq;
using System.Text;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.pdf.richmedia;
 
namespace kuujinbo.iTextInAction2Ed.Chapter16 {
  public class FestivalCalendar2 : IWriter {
// ===========================================================================
    /** The path to a Flash application. */
    public readonly String RESOURCE = Path.Combine(
      Utility.ResourceSwf, "FestivalCalendar2.swf"
    );
    /** The path to a JavaScript file. */
    public readonly String JS = Path.Combine(
      Utility.ResourceJavaScript, "show_date.js"
    );
// ---------------------------------------------------------------------------
    public void Write(Stream stream) {
      // step 1
      using (Document document = new Document()) {
        // step 2
        PdfWriter writer = PdfWriter.GetInstance(document, stream);
        writer.SetPdfVersion(PdfWriter.PDF_VERSION_1_7);
        writer.AddDeveloperExtension(
          PdfDeveloperExtension.ADOBE_1_7_EXTENSIONLEVEL3
        );
        // step 3
        document.Open();
        // step 4
        writer.AddJavaScript(File.ReadAllText(JS));
 
        // we prepare a RichMediaAnnotation
        RichMediaAnnotation richMedia = new RichMediaAnnotation(
          writer, new Rectangle(36, 560, 561, 760)
        );
        // we embed the swf file
        PdfFileSpecification fs = PdfFileSpecification.FileEmbedded(
          writer, RESOURCE, "FestivalCalendar2.swf", null
        );
        // we declare the swf file as an asset
        PdfIndirectReference asset = richMedia.AddAsset(
          "FestivalCalendar2.swf", fs
        );
        // we create a configuration
        RichMediaConfiguration configuration = new RichMediaConfiguration(
          PdfName.FLASH
        );
        RichMediaInstance instance = new RichMediaInstance(PdfName.FLASH);
        instance.Asset = asset;
        configuration.AddInstance(instance);
        // we add the configuration to the annotation
        PdfIndirectReference configurationRef = richMedia.AddConfiguration(
          configuration
        );
        // activation of the rich media
        RichMediaActivation activation = new RichMediaActivation();
        activation.Configuration = configurationRef;
        richMedia.Activation = activation;
        // we add the annotation
        PdfAnnotation richMediaAnnotation = richMedia.CreateAnnotation();
        richMediaAnnotation.Flags = PdfAnnotation.FLAGS_PRINT;
        writer.AddAnnotation(richMediaAnnotation);
        
        String[] days = new String[] {
          "2011-10-12", "2011-10-13", "2011-10-14", "2011-10-15",
          "2011-10-16", "2011-10-17", "2011-10-18", "2011-10-19"
        };
        for (int i = 0; i < days.Length; i++) {
          Rectangle rect = new Rectangle(36 + (65 * i), 765, 100 + (65 * i), 780);
          PushbuttonField button = new PushbuttonField(writer, rect, "button" + i);
          button.BackgroundColor = new GrayColor(0.75f);
          button.BorderStyle = PdfBorderDictionary.STYLE_BEVELED;
          button.TextColor = GrayColor.GRAYBLACK;
          button.FontSize = 12;
          button.Text = days[i];
          button.Layout = PushbuttonField.LAYOUT_ICON_LEFT_LABEL_RIGHT;
          button.ScaleIcon = PushbuttonField.SCALE_ICON_ALWAYS;
          button.ProportionalIcon = true;
          button.IconHorizontalAdjustment = 0;
          PdfFormField field = button.Field;
          RichMediaCommand command = new RichMediaCommand(
            new PdfString("getDateInfo")
          );
          command.Arguments = new PdfString(days[i]);
          RichMediaExecuteAction action = new RichMediaExecuteAction(
            richMediaAnnotation.IndirectReference, command
          );
          field.Action = action;
          writer.AddAnnotation(field);
        }
        TextField text = new TextField(
          writer, new Rectangle(36, 785, 559, 806), "date"
        );
        text.Options = TextField.READ_ONLY;
        writer.AddAnnotation(text.GetTextField());
      }
    }
// ===========================================================================
    }
}


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