Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

PDF made easy with iText 7

3,885 views

Published on

Another look at iText 7 from the Great Indian Developer Summit in 2016

Published in: Software
  • D0WNL0AD FULL ▶ ▶ ▶ ▶ http://1lite.top/yUQVE ◀ ◀ ◀ ◀
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

PDF made easy with iText 7

  1. 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. 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. 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. 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.
  5. 5. iText 7: modular approach
  6. 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();
  7. 7. iText’s basic building blocks: examples
  8. 8. Hello world: code OutputStream fos = new FileOutputStream(dest); PdfWriter writer = new PdfWriter(fos); PdfDocument pdf = new PdfDocument(writer); Document document = new Document(pdf); document.add(new Paragraph("Hello World!")); document.close();
  9. 9. Hello world: result
  10. 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. 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);
  12. 12. List example: result
  13. 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. 14. New in iText 7: improved typography and support for Indic scripts
  15. 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. 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. 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
  18. 18. Indic scripts: examples PdfFont font = PdfFontFactory.createFont(arial, PdfEncodings.IDENTITY_H, true); String txt = "u0938u093Eu0939u093Fu0924u094Du092Fu0915u093Eu0930"; // saahityakaar document.add(new Paragraph(txt).setFont(font)); String txt = "u0B8Eu0BB4u0BC1u0BA4u0BCDu0BA4u0BBEu0BB3u0BB0u0BCD"; // eluttaalar document.add(new Paragraph(txt).setFont(font));
  19. 19. Other scripts: examples PdfFont font = PdfFontFactory.createFont(arial, PdfEncodings.IDENTITY_H, true); String txt = " u0627u0644u0643u0627u062Au0628"; // al-katibu document.add(new Paragraph(txt).setFont(font)); String txt = "writer"; GlyphLine glyphLine = font.createGlyphLine(txt); Shaper.applyLigaFeature(foglihtenNo07, glyphLine, null); canvas.showText(glyphLine)
  20. 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
  21. 21. Real-world use: Publishing a database CSV example
  22. 22. Imagine a series of records
  23. 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. 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))); } } }
  25. 25. CSV: resulting report
  26. 26. Form filling Form flattening
  27. 27. Example form
  28. 28. Look inside your PDF
  29. 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();
  30. 30. Result after filling
  31. 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();
  32. 32. Result after flattening
  33. 33. Form flattening Merging
  34. 34. United States: Example form
  35. 35. Flatten and merge PdfDocument destPdfDocument = new PdfDocument(new PdfWriter(dest)); BufferedReader bufferedReader = new BufferedReader(new FileReader(DATA)); String line; while ((line = bufferedReader.readLine()) != null) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); PdfDocument sourcePdfDocument = new PdfDocument(new PdfReader(SRC), new PdfWriter(baos)); PdfAcroForm form = PdfAcroForm.getAcroForm(sourcePdfDocument, true); StringTokenizer tokenizer = new StringTokenizer(line, ";"); Map<String, PdfFormField> fields = form.getFormFields(); fields.get("name").setValue(tokenizer.nextToken()); form.flattenFields(); sourcePdfDocument.close(); sourcePdfDocument = new PdfDocument( new PdfReader(new ByteArrayInputStream(baos.toByteArray()))); sourcePdfDocument.copyPagesTo(1, sourcePdfDocument.getNumberOfPages(), destPdfDocument, null); sourcePdfDocument.close(); } bufferedReader.close(); destPdfDocument.close();
  36. 36. The result (and why we don’t like it)
  37. 37. Flatten and merge PdfWriter writer = new PdfWriter(dest).setSmartMode(true); PdfDocument destPdfDocument = new PdfDocument(writer); BufferedReader bufferedReader = new BufferedReader(new FileReader(DATA)); String line; while ((line = bufferedReader.readLine()) != null) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); PdfDocument sourcePdfDocument = new PdfDocument(new PdfReader(SRC), new PdfWriter(baos)); PdfAcroForm form = PdfAcroForm.getAcroForm(sourcePdfDocument, true); StringTokenizer tokenizer = new StringTokenizer(line, ";"); Map<String, PdfFormField> fields = form.getFormFields(); fields.get("name").setValue(tokenizer.nextToken()); form.flattenFields(); sourcePdfDocument.close(); sourcePdfDocument = new PdfDocument( new PdfReader(new ByteArrayInputStream(baos.toByteArray()))); sourcePdfDocument.copyPagesTo(1, sourcePdfDocument.getNumberOfPages(), destPdfDocument, null); sourcePdfDocument.close(); } bufferedReader.close(); destPdfDocument.close();
  38. 38. The result (much better than before)

×