The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
PDF made easy with iText 7
1. PDF made easy with iText 7
What’s new in iText and iTextSharp?
Benoit Lagae, Developer, iText Software
Bruno Lowagie, Chief Strategy Officer, iText Group
2. Why did we write iText?
• Specific problems that needed to be solved
– Emancipate PDF from the desktop to the server
• Solved in 1998 with a first PDF library
• Deep knowledge of PDF required
– Make PDF creation easier for developers
• Solved in 2000 with the release of iText
• Concept: PdfWriter and Document
• Add high-level objects (e.g. paragraph, list, table)
3. History
• First release: 2000
• iText 1: 2003
• iText 2: 2007
• iText 5: 2009; upgrade to Java 5
• iText 7: 2016; upgrade to Java 7
iText is available for Java and .NET
4. Why iText 7?
iText 5 was approaching the limits of its architecture.
iText 7 overcomes these limits and enables further user-driven feature
development and more efficient support
• Complete revision of all classes and interfaces based on experience
with iText 5.
• Complete new layout module, which resolves some inconsistencies
in iText 5 and enables generation of complex layouts.
• Complete rewrite of font support enabling advanced typography.
6. Basic design principle
OutputStream fos = new FileOutputStream(dest);
PdfWriter writer = new PdfWriter(fos);
PdfDocument pdf = new PdfDocument(writer);
// PDF knowledge needed to add content
pdf.close();
OutputStream fos = new FileOutputStream(dest);
PdfWriter writer = new PdfWriter(fos);
PdfDocument pdf = new PdfDocument(writer);
Document document = new Document(pdf);
// No PDF knowledge needed to add content
document.close();
10. Hello world: the hard way
FileOutputStream fos = new FileOutputStream(dest);
PdfWriter writer = new PdfWriter(fos);
PdfDocument pdf = new PdfDocument(writer);
PageSize ps = PageSize.A4;
PdfPage page = pdf.addNewPage(ps);
PdfCanvas canvas = new PdfCanvas(page);
canvas.beginText()
.setFontAndSize(
PdfFontFactory.createFont(FontConstants.HELVETICA), 12)
.moveText(36, 790)
.showText("Hello World!")
.endText();
pdf.close();
11. List example: code
// Create a PdfFont
PdfFont font = PdfFontFactory.createFont(FontConstants.TIMES_ROMAN);
// Add a Paragraph
document.add(new Paragraph("iText is:").setFont(font));
// Create a List
List list = new List()
.setSymbolIndent(12)
.setListSymbol("u2022")
.setFont(font);
// Add ListItem objects
list.add(new ListItem("Never gonna give you up"))
.add(new ListItem("Never gonna let you down"))
.add(new ListItem("Never gonna run around and desert you"))
.add(new ListItem("Never gonna make you cry"))
.add(new ListItem("Never gonna say goodbye"))
.add(new ListItem("Never gonna tell a lie and hurt you"));
// Add the list
document.add(list);
13. Image example
Image fox = new Image(ImageFactory.getImage(FOX));
Image dog = new Image(ImageFactory.getImage(DOG));
Paragraph p = new Paragraph("Quick brown ").add(fox)
.add(" jumps over the lazy ").add(dog);
document.add(p);
14. New in iText 7:
improved typography
and support for Indic scripts
15. iText 5: missing links
Indic scripts:
•Only unsupported major script family
•Feature request #1
•Huge opportunity
•limited support in most other PDF libraries
Other features:
•Optional ligatures in Latin script
•Vowel diacritics in Arabic
16. Indic scripts: problems
•Lack of expertise
•Unicode encodes 49 Indic scripts
•Complex scripts with unique features
•Glyph repositioning: ह + ि = िह
•Glyph substitution: ம + ு = மு
•Half-characters: त + + य = त्य
•Unsolvable issues for iText 5 font engine
•No dedicated Unicode points for half-characters
•No font lookups past ‘uFFFF’
•Ligaturization is context-dependent (virama)
17. Indic scripts: solutions
Writing a new font engine
• Automatic script recognition
• Based on Unicode ranges
• Flexibility = extensibility
• Generic Shaper class
• Separate module, only called when necessary
• Glyph replacement rules
• Different per writing system
• Alternate glyphs are font-dependent
20. Status of advanced
typography in iText 7
•Indic scripts
•We already support:
•Devanagari
•Tamil
•Coming soon:
•Telugu
•Others: based on customer demand
•Arabic
•Support for vocalized Arabic (diacritics) is in development
•Latin
•Optional ligatures are fully supported
23. Parse CSV line by line
OutputStream fos = new FileOutputStream(dest);
PdfWriter writer = new PdfWriter(fos);
PdfDocument pdf = new PdfDocument(writer);
Document document = new Document(pdf, PageSize.A4.rotate());
document.setMargins(20, 20, 20, 20);
PdfFont font = PdfFontFactory.createFont(FontConstants.HELVETICA);
PdfFont bold = PdfFontFactory.createFont(FontConstants.HELVETICA_BOLD);
Table table = new Table(new float[]{4, 1, 3, 4, 3, 3, 3, 3, 1});
table.setWidthPercent(100);
BufferedReader br = new BufferedReader(new FileReader(DATA));
String line = br.readLine();
process(table, line, bold, true);
while ((line = br.readLine()) != null) {
process(table, line, font, false);
}
br.close();
document.add(table);
document.close();
24. Process each line
public void process(Table table, String line,
PdfFont font, boolean isHeader) {
StringTokenizer tokenizer = new StringTokenizer(line, ";");
while (tokenizer.hasMoreTokens()) {
if (isHeader) {
table.addHeaderCell(
new Cell().add(
new Paragraph(tokenizer.nextToken()).setFont(font)));
} else {
table.addCell(
new Cell().add(
new Paragraph(tokenizer.nextToken()).setFont(font)));
}
}
}
29. Fill the form
PdfReader reader = new PdfReader(src);
PdfWriter writer = new PdfWriter(dest);
PdfDocument pdf = new PdfDocument(reader, writer);
PdfAcroForm form = PdfAcroForm.getAcroForm(pdf, true);
Map<String, PdfFormField> fields = form.getFormFields();
fields.get("name").setValue("James Bond");
fields.get("language").setValue("English");
fields.get("experience1").setValue("Off");
fields.get("experience2").setValue("Yes");
fields.get("experience3").setValue("Yes");
fields.get("shift").setValue("Any");
fields.get("info").setValue("I was 38 years old when I became an MI6 agent.");
pdf.close();
31. Flatten the form
PdfReader reader = new PdfReader(src);
PdfWriter writer = new PdfWriter(dest);
PdfDocument pdf = new PdfDocument(reader, writer);
PdfAcroForm form = PdfAcroForm.getAcroForm(pdf, true);
Map<String, PdfFormField> fields = form.getFormFields();
fields.get("name").setValue("James Bond");
fields.get("language").setValue("English");
fields.get("experience1").setValue("Off");
fields.get("experience2").setValue("Yes");
fields.get("experience3").setValue("Yes");
fields.get("shift").setValue("Any");
fields.get("info").setValue("I was 38 years old when I became an MI6 agent.");
form.flattenFields();
pdf.close();