JavaBeat

  • Home
  • Java
    • Java 7
    • Java 8
    • Java EE
    • Servlets
  • Spring Framework
    • Spring Tutorials
    • Spring 4 Tutorials
    • Spring Boot
  • JSF Tutorials
  • Most Popular
    • Binary Search Tree Traversal
    • Spring Batch Tutorial
    • AngularJS + Spring MVC
    • Spring Data JPA Tutorial
    • Packaging and Deploying Node.js
  • About Us
    • Join Us (JBC)
  • Privacy

How to Protect PDF with Password using iText in Java?

October 27, 2013 by Krishna Srinivasan Leave a Comment

In my previous article I have explained about how to create PDF document using iText with simple example. This tutorial explains how to add a password protection for your PDF document. iText doesn’t provide the password feature in its own API, however it internally uses another third part implementation and implements the password protection.

iText internally uses the library bouncycastle to generate the password PDF file. You have to download the JAR file from the given link before run the below example. Once the PDF is created, you will be asked for the password when open the document. pdfWriter.setEncryption is taking the bytes array as the arguments, so you need to convert your inputs to bytes and pass it.

  • Reading Excel using Apache POI

[code lang=”java”]
package javabeat.net.pdf;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;

import com.itextpdf.text.Document;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfWriter;

public class PDFConversionDemo {
public static void main(String[] args) {
try {
OutputStream file = new FileOutputStream(new File("SamplePDF.pdf"));
Document document = new Document();
PdfWriter pdfWriter = PdfWriter.getInstance(document, file);
pdfWriter.setEncryption("krishna".getBytes(), "testpass".getBytes(),
PdfWriter.ALLOW_PRINTING, PdfWriter.ENCRYPTION_AES_128);
document.open();
document.add(new Paragraph("First iText PDF"));
document.close();
file.close();

} catch (Exception e) {

e.printStackTrace();
}
}

}
[/code]

itext-pdf-password
itext-pds-password-doc

Filed Under: Java Tagged With: iText, PDF

How to Create PDF using iText in Java?

October 27, 2013 by Krishna Srinivasan Leave a Comment

Generating PDF report is the very general requirement in most of the Java projects. iText is the most popular PDF API used by the Java developers for generating the PDF report. It is very simple and easy to get started writing simple PDF files. If you are familiar with iText API,  it provides more advanced features to format the PDF output as you need. This tutorial explains with simple Java program that helps you to generate a PDF file with sample text and table. If you have any questions, please write it in the comments section.

1. Add iText Libraries

You can download the iText jar files from here. There is three types of JAR files.

  1. itextpdf-x.y.z.jar: the core library
  2. itext-xtra-x.y.z.jar: extra functionality
  3. itext-pdfa-x.y.z.jar: PDF/A-related functionality

2. Create PDF Conversion Utility Java File

[code lang=”java”]
package javabeat.net.pdf;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.Date;

import com.itextpdf.text.Document;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;

public class PDFConversionDemo {
public static void main(String[] args) {
try {
OutputStream file = new FileOutputStream(new File("SamplePDF.pdf"));

Document document = new Document();
PdfWriter.getInstance(document, file);

document.open();
document.add(new Paragraph("First iText PDF"));
document.add(new Paragraph(new Date().toString()));

document.addAuthor("Krishna Srinivasan");
document.addCreationDate();
document.addCreator("JavaBeat");
document.addTitle("Sample PDF");

//Create Paragraph
Paragraph paragraph = new Paragraph("Title 1",new Font(Font.FontFamily.TIMES_ROMAN, 18,
Font.BOLD));

//New line
paragraph.add(new Paragraph(" "));
paragraph.add("Test Paragraph");
paragraph.add(new Paragraph(" "));
document.add(paragraph);

//Create a table in PDF
PdfPTable pdfTable = new PdfPTable(3);
PdfPCell cell1 = new PdfPCell(new Phrase("Table Header 1"));
cell1.setHorizontalAlignment(Element.ALIGN_CENTER);
pdfTable.addCell(cell1);

cell1 = new PdfPCell(new Phrase("Table Header 2"));
cell1.setHorizontalAlignment(Element.ALIGN_CENTER);
pdfTable.addCell(cell1);

cell1 = new PdfPCell(new Phrase("Table Header 3"));
cell1.setHorizontalAlignment(Element.ALIGN_CENTER);
pdfTable.addCell(cell1);
pdfTable.setHeaderRows(1);

pdfTable.addCell("Row 1 Col 1");
pdfTable.addCell("Row 1 Col 2");
pdfTable.addCell("Row 1 Col 3");

pdfTable.addCell("Row 2 Col 1");
pdfTable.addCell("Row 2 Col 2");
pdfTable.addCell("Row 2 Col 3");

document.add(pdfTable);

document.close();
file.close();

} catch (Exception e) {

e.printStackTrace();
}
}

}
[/code]

3. Project Structure

It is simple Java project. Look at the project folder structure.

iText PDF Project Folder Structure

4. Output

If you run the above program, you would have a new PDF generated in the location mentioned above section. The PDF would look like this.

iText PDF Same PDF Report

Filed Under: Java Tagged With: iText

Resizing an Image in an Existing Document using iText

May 11, 2011 by Krishna Srinivasan Leave a Comment

This article is based on iText in Action, Second Edition, published on October, 2010. It is being reproduced here by permission from Manning Publications. Manning publishes MEAP (Manning Early Access Program,) eBooks and pBooks. MEAPs are sold exclusively through Manning.com. All pBook purchases include free PDF, mobi and epub. When mobile formats become available all customers will be contacted and upgraded. Visit Manning.com for more information. [ Use promotional code ‘java40beat’ and get 40% discount on eBooks and pBooks ]

also read:

  • Java Tutorials
  • Java EE Tutorials
  • Design Patterns Tutorials
  • Java File IO Tutorials

Resizing an Image in an Existing Document

Introduction

Here’s a question that is often posted to the mailing list: “How do we reduce the size of an existing PDF containing lots of images?” There are many different answers to this question, depending on the nature of the PDF file. Maybe the same image is added multiple times, in which case passing the PDF through PdfSmartCopy could already result in a serious file size reduction. Maybe the PDF wasn’t compressed or maybe there are plenty of unused objects. You could try and see if the PdfReader method removeUnusedObjects() yields any results.

It’s more likely that the PDF contains high-resolution images, in which case the original question should be rephrased into, “How do I reduce the resolution of the images inside my PDF?” To achieve this, we should extract the image from the PDF, downsample it, and then put it back into the PDF, replacing the high-resolution image. Listing 1 uses brute force instead of the PdfReaderContentParser to find images. With the method getXrefSize() we get the highest object number in the PDF document and we loop over every object, searching for a stream that has the special id we’re looking for.

Listing 1 ResizeImage.java

[code lang=”java”]PdfName key = new PdfName("ITXT_SpecialId");
PdfName value = new PdfName("123456789");
PdfReader reader = new PdfReader(SpecialId.RESULT);
int n = reader.getXrefSize();
PdfObject object;
PRStream 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);
}
}
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(RESULT));
stamper.close();

A Finds the image stream
B Gets the BufferedImage
C Creates a new BufferedImage
D Writes JPG bytes
E Replaces the content of the image stream<[/code]

Once we’ve found the stream we need, we create a PdfImageObject that will create us a java.awt.image.BufferedImage named bi. We’ll create a second BufferedImage named img that is a factor smaller. In this example, the value of FACTOR is 0.5. We draw the image bi to the Graphics2D object of the image image using an affine transformation that scales the image down with a factor FACTOR.

We write the image as a JPEG to a ByteArrayOutputStream. We use the bytes from this OutputStream as the new data for the stream object we’ve retrieved from PdfReader. We reset all the entries in the image dictionary and we add all the keys that are necessary for a PDF viewer to interpret the image bytes correctly. After changing the PRStream object in the reader, we use PdfStamper to write the altered file to a FileOutputStream. Again we get a look at the way iText works internally. When we add a JPEG to a document the normal way, iText selects all the entries for the image dictionary for us.

Working at the lowest level is fun and gives you a lot of power but you really have to know what you’re doing; otherwise, you can seriously damage a PDF file. Because of the high complexity, some requirements are close to impossible. For instance, it’s very hard to replace a font.

Summary

We discussed resizing images in a PDF. We used the method getXrefSize()to get the highest object number in the PDF document. Then, we created a PdfImageObject that produces a java.awt.image.BufferedImage named bi. Next, we created a second, smaller BufferedImage named img. We drew the image bi to the Graphics2D object of the image image using an affine transformation that scales the image down with a factor FACTOR. We wrote the image as a JPEG to a ByteArrayOutputStream. We used the bytes from this OutputStream as the new data for the stream object we’ve retrieved from PdfReader. We reset all the entries in the image dictionary and we added all the keys for a PDF viewer to interpret the image bytes correctly. After changing the PRStream object in the reader, we used PdfStamper to write the altered file to a FileOutputStream.

Filed Under: Java Tagged With: iText

Replacing a Font using iText

May 11, 2011 by Krishna Srinivasan Leave a Comment

This article is based on iText in Action, Second Edition, published on October, 2010. It is being reproduced here by permission from Manning Publications. Manning publishes MEAP (Manning Early Access Program,) eBooks and pBooks. MEAPs are sold exclusively through Manning.com. All pBook purchases include free PDF, mobi and epub. When mobile formats become available all customers will be contacted and upgraded. Visit Manning.com for more information. [ Use promotional code ‘java40beat’ and get 40% discount on eBooks and pBooks ]

also read:

  • Java Tutorials
  • Java EE Tutorials
  • Design Patterns Tutorials
  • Java File IO Tutorials

Replacing a Font

Introduction

Figure 1 shows two PDF files that were created in exactly the same way, except for one difference: in the top PDF, the font (Walt Disney Script v4.1) wasn’t embedded. It’s a font I’ve downloaded from a site with plenty of free fonts. The font isn’t installed on my operating system. As a result, Adobe Reader doesn’t find it, and the words “iText in Action” are shown in Adobe Sans MM, which is quite different from the font shown in the PDF that has the font embedded.

If we had the top PDF as well as the font file for the Walt Disney Script font, we could use listing 1 to embed that font after the fact.

Listing 1 EmbedFontPostFacto.java

[code lang=”java”]RandomAccessFile raf = new RandomAccessFile(FONT, "r"); A
byte fontfile[] = new byte[(int)raf.length()]; A
raf.readFully(fontfile); A
raf.close(); A
PdfStream stream = new PdfStream(fontfile); B
stream.flateCompress(); B
stream.put(PdfName.LENGTH1, new PdfNumber(fontfile.length)); B
PdfReader reader = new PdfReader(RESULT1);
int n = reader.getXrefSize();
PdfObject object;
PdfDictionary font;
PdfStamper stamper
= new PdfStamper(reader, new FileOutputStream(RESULT2));
PdfName fontname = new PdfName(FONTNAME);
for (int i = 0; i < n; i++) { C
object = reader.getPdfObject(i); C
if (object == null || !object.isDictionary()) C
continue; C
font = (PdfDictionary)object; C
if (PdfName.FONTDESCRIPTOR.equals(font.get(PdfName.TYPE)) C
&& fontname.equals(font.get(PdfName.FONTNAME))) { C
PdfIndirectObject objref = stamper.getWriter().addToBody(stream); D
font.put(PdfName.FONTFILE2, objref.getIndirectReference()); E
}
}
stamper.close();

A Reads the font file into a byte array
B Creates a PDF stream
C Finds the unembedded font
D Adds the stream to the writer
E Adds the reference to the stream[/code]

Note that we’re adding the complete font file in this example. We add the reference to the stream using the key FONTFILE2 because we know in advance that the font has True Type outlines. That’s not the only assumption we make. We also assume that the metrics of the font that is used in the PDF correspond with the metrics of the new font we’re embedding.

As for parsing PDF, we could only do a fair attempt, but the functionality could fail for PDFs using exotic encodings. In real world examples, replacing one font with another can be very difficult.

Summary

In this article, I showed you how to replace a font in a PDF document using the embed feature in iText.

Filed Under: Java Tagged With: iText

Making Content Visible or Invisible using iText PDF Framework

May 11, 2011 by Krishna Srinivasan Leave a Comment

This article is based on iText in Action, Second Edition, published on October, 2010. It is being reproduced here by permission from Manning Publications. Manning publishes MEAP (Manning Early Access Program,) eBooks and pBooks. MEAPs are sold exclusively through Manning.com. All pBook purchases include free PDF, mobi and epub. When mobile formats become available all customers will be contacted and upgraded. Visit Manning.com for more information. [ Use promotional code ‘java40beat’ and get 40% discount on eBooks and pBooks ]

also read:

  • Java Tutorials
  • Java EE Tutorials
  • Design Patterns Tutorials
  • Java File IO Tutorials

Making Content Visible or Invisible

Introduction

Beginning with PDF 1.5, we can also add optional content: content that can be selectively viewed or hidden by document authors or consumers. Graphics and text that can be made visible or invisible dynamically are grouped in an optional content group (OCG). Content that belongs to a certain group is visible when the group is on and invisible when the group is off. Figure 1 demonstrates this functionality.

The text “Do you see me?” is added as normal content. The text “Peek-a-Boo!!!” is added as optional content. This text is visible in the upper window but not in the lower window. In both windows the Layers panel is opened. “Do you see me?” is the caption of a layer (which is another name for OCG). By clicking on the group’s checkbox in the Layers panel, end users can make the content visible or invisible.

Listing 1 shows how the “Do you see me?” layer was created using iText’s PdfLayer object and how the text “Peek-a-Boo!!!” was made optional using the PdfContentByte methods beginLayer() and endLayer().

Listing 1 PeekABoo.java

[code lang=”java”]Document document = new Document();
PdfWriter writer
= PdfWriter.getInstance(document, new FileOutputStream(filename));
writer.setViewerPreferences(PdfWriter.PageModeUseOC);
writer.setPdfVersion(PdfWriter.VERSION_1_5);
document.open();
PdfLayer layer = new PdfLayer("Do you see me?", writer); A
layer.setOn(on); A
BaseFont bf = BaseFont.createFont();
PdfContentByte cb = writer.getDirectContent();
cb.beginText();
cb.setFontAndSize(bf, 18);
cb.showTextAligned(Element.ALIGN_LEFT, "Do you see me?", 50, 790, 0); B
cb.beginLayer(layer); C
cb.showTextAligned(Element.ALIGN_LEFT, "Peek-a-Boo!!!", 50, 766, 0); C
cb.endLayer(); C
cb.endText();
document.close();

A Creating a layer
B Adding normal content
C Adding optional content[/code]

Note that we’ve set the viewer preferences so that the optional content panel is shown when the document is opened. The state of the layers can be specified with the method setOn(). This method expects a Boolean value. If true, the layer will be visible (this is the default). If false, the layer will be hidden.

If you’d peek into the content stream of the resulting page, you’d see this construct:

[code]/OC /Pr1 BDC
1 0 0 1 50 766 Tm
(Peek-a-Boo!!!)Tj
EMC[/code]

The optional content is put between the marked-content operators BDC and EDC. This marked content is recognized as optional because of the tag /OC. The operand /Pr1 was created by iText. You’ll find a reference to the OCG in the resources dictionary of the page:

[code]/Properties<</Pr1 1 0 R>>[/code]

The indirect object 1 looks like this:

[code]1 0 obj
<</Type/OCG/Name(Do you see me?)>>
endobj[/code]

The optional content groups and their properties are listed in the catalog:

[code]<<
/Type/Catalog
/Pages 4 0 R
/OCProperties<<
/D<<
/Order[1 0 R]
/ListMode/VisiblePages
>>
/OCGs[1 0 R]
>>
/PageMode/UseOC
>>[/code]

Optional content of a group can reside anywhere in the document. It doesn’t have to be consecutive in the drawing order or belong to the same content stream (or page).

Summary

In this article, we added structures that made part of the content optional, a feature that’s been available beginning with PDF 1.5.

Filed Under: Java Tagged With: iText, PDF

JavaScript in PDF Documents using iText

April 23, 2011 by Krishna Srinivasan Leave a Comment

This article is based on iText in Action, Second Edition, published on October, 2010. It is being reproduced here by permission from Manning Publications. Manning publishes MEAP (Manning Early Access Program,) eBooks and pBooks. MEAPs are sold exclusively through Manning.com. All pBook purchases include free PDF, mobi and epub. When mobile formats become available all customers will be contacted and upgraded. Visit Manning.com for more information. [ Use promotional code ‘java40beat’ and get 40% discount on eBooks and pBooks ]

also read:

  • Java Tutorials
  • Java EE Tutorials
  • Design Patterns Tutorials
  • Java File IO Tutorials

Introduction

JavaScript is a scripting language that is primarily used to add client-side functionality to an HTML page and to create dynamic web sites. It allows programmatic access to objects within the web browser. JavaScript is also available in PDF viewers such as Adobe Reader. There’s a JavaScript API for PDF documents that extends the core Client-Side JavaScript specification and gives you access to Acrobat and Adobe Reader objects. Initially, JavaScript 1.2 was used. Since Acrobat 5.0, the API is based on JavaScript 1.5. The most recent versions of Acrobat and Adobe Reader (since 8.0) use JavaScript 1.6. If you want to know more about the complete set of objects and functions, you can download the PDFs “Developing Acrobat Applications Using JavaScript” and the “JavaScript for Acrobat API Reference” from the adobe.com site. We’re going to use some of the objects listed in that reference to learn how to introduce JavaScript in a PDF document using iText.

Document-level JavaScript

Listing 1 is an example of a simple script that clears the JavaScript console window, makes it visible, and writes information about the viewer and its version number.

Listing 1 viewer_version.js

[code lang=”java”]console.clear();
console.show();
console.println("Hello");
console.println("You are using: " + app.viewerType);
console.println("The version of " + app.viewerType
+ " is: " + app.viewerVersion);[/code]

The console is an object that originally wasn’t available in Adobe Reader—only in Acrobat. It was introduced in Adobe Reader 7.0 to report errors and show messages. In our example, we print the value of the viewerType and viewerVersion property of the application (the app object) to the console.

Figure 1 JavaScript Console Window
Figure 1 shows that I’ve opened the document in Adobe Reader version 9.2. Listing 1 was added to an existing PDF document using the code in listing 2.

Listing 2 AddVersionChecker

[code lang=”java”]
PdfReader reader = new PdfReader(HelloWorld.RESULT);
PdfStamper stamper =
new PdfStamper(reader, new FileOutputStream(RESULT));
stamper.addJavaScript(Utilities.readFileToString(RESOURCE));
stamper.close();[/code]

Note that what we’re doing in listing 1 and 2 isn’t very elegant. It works, but the addJavaScript() method should only be used to add JavaScript functions that can be called from a JavaScript action.

JavaScript actions

Suppose you had a day-to-day overview of all the movies that are screened at a festival. Let’s say the movies are sorted by date and time, but you’d like to offer extra functionality that allows the end user to search for the occurrence of a specific director in the document. See figure 2.

Figure 2 Search window in Adobe Reader
This can be achieved with the search object using code in listing 3.

Listing 3 find_director.js

[code lang=”java”]function findDirector(name) {
if (search.available) {
search.query(name, "ActiveDoc");
}
else {
app.alert("The Search plug-in isn’t installed.");
}
}[/code]

Note that we first check for the availability of the Search plug-in, because we mustn’t assume that the plug-in is installed in every PDF viewer. If the plug-in is missing, we inform the end user that searching for directors won’t work using the method app.alert(). This method is similar to the alert() method in plain JavaScript. The viewer application opens an alert box showing the String that is passed to the method.
FAQ

Why are some of the methods I’ve found in the API documentation not working? If you look for the query() method in the API documentation provided by Adobe, you’ll see that the method is marked with a red “S”. This means that the usage of the method can be restricted because of security reasons. Some methods only work in the full Acrobat application and not in the free Reader. Or, they are only supposed to work when the document is certified or reader enabled. Please check the “JavaScript for Acrobat API Reference” before reporting problems with JavaScript.

In listing 4, we’re calling the method shown in listing 3 from an action.

Listing 3 find_director.js

[code lang=”java”]public void createPdf(String filename)
…
PdfReader[] readers = {
new PdfReader(baos.toByteArray()), A
new PdfReader(NestedTables.RESULT) }; B
Document document = new Document();
PdfCopy copy = new PdfCopy(document, new FileOutputStream(filename)); C
document.open();
copy.addJavaScript(Utilities.readFileToString(RESOURCE)); 1
int n;
for (int i = 0; i < readers.length; i++) {
n = readers[i].getNumberOfPages();
for (int page = 0; page < n; ) {
copy.addPage(copy.getImportedPage(readers[i], ++page));
}
}
document.close();
}
public Paragraph createDirectorParagraph(PdfWriter writer, ResultSet rs)
throws UnsupportedEncodingException, SQLException {
String n = new String(rs.getBytes("name"), "UTF-8");
Chunk name = new Chunk(n);
name.setAction(PdfAction.javaScript( 2
String.format("findDirector(‘%s’);", n), writer)); 2
name.append(", ");
name.append(new String(rs.getBytes("given_name"), "UTF-8"));
return new Paragraph(name);
}
[/code]

 

[code]
A A new document with the search actions
B The original document
C Concatenates the two documents
1 Adds the js function to the document
2 Creates an action that uses the function[/code]

We add the function findDirector(name) as document-level JavaScript #1. We use that function in the first document in actions that are triggered when the end user clicks on the name of a director #2.

Summary

This article discussed some of the interactive features that can be added to a document. We found out that there are other types of actions besides link actions, for instance JavaScript actions. We’ve used this knowledge to create a search feature.

Filed Under: Java Tagged With: iText, PDF

JavaScript Communication between HTML and PDF in iText

April 23, 2011 by Krishna Srinivasan Leave a Comment

This article is based on iText in Action, Second Edition, published on October, 2010. It is being reproduced here by permission from Manning Publications. Manning publishes MEAP (Manning Early Access Program,) eBooks and pBooks. MEAPs are sold exclusively through Manning.com. All pBook purchases include free PDF, mobi and epub. When mobile formats become available all customers will be contacted and upgraded. Visit Manning.com for more information. [ Use promotional code ‘java40beat’ and get 40% discount on eBooks and pBooks ]

also read:

  • Java Tutorials
  • Java EE Tutorials
  • Design Patterns Tutorials
  • Java File IO Tutorials

Introduction

Imagine the following situation: you have a catalogue with thousands of items stored in a database. People can purchase these items online using a PDF form. How will you create that form? Surely, you don’t want to embed your complete article database in a choice field inside your PDF. It would be much easier to provide browse or search functionality in an HTML page and then find a way to pass this data from the HTML pages to the PDF form.

Figure 1 shows an HTML page with a form and an embedded PDF document. The HTML form has two fields and a button. If you fill out a name and login and click the button, the values entered in the fields are passed as a message to the PDF document. The PDF document accepts these values and fills out the corresponding fields in the AcroForm.

Figure 1 JavaScript communication between HTML and PDFPassing the values in the opposite direction is also possible. If you change the name and login in the PDF form and click the button “POST TO HTML”, the entries are passed from the PDF form to the HTML form.

Listing 1 javascript.html

[code lang=”html”]<html>
<head>
<script language="javascript">
function createMessageHandler() { 1
var PDFObject = document.getElementById("myPdf"); 1
PDFObject.messageHandler = { 1
onMessage: function(msg) { 1
document.personal.name.value = msg[0]; 1
document.personal.loginname.value = msg[1]; 1
}, 1
onError: function(error, msg) { 1
alert(error.message); 1
} 1
} 1
} 1
function sendToPdf() { 2
var PDFObject = document.getElementById("myPdf"); 2
if(PDFObject!= null){ 2
PDFObject.postMessage( 2
[document.personal.name.value, 2
document.personal.loginname.value]); 2
} 2
} 2
</script>
</head>
<body onLoad="createMessageHandler();">
<form name="personal"> A
<table> A
<tr> A
<td>Name:</td> A
<td><input type="Text" name="name"></td> A
<td>Login:</td> A
<td><input type="Text" name="loginname"></td> A
<td><input type="Button" value="Send to PDF" A
onClick="return sendToPdf();"></td> A
</tr> A
</table> A
</form> A
<object id="myPdf" type="application/pdf" data="javascript.pdf" B
height="100%" width="100%"></object> B
</body>
</html>

1 JavaScript to get data from the PDF
2 JavaScript to send data to the PDF
A The HTML form
B Embedding the PDF as an object[/code]

Embedding a PDF document as an HTML object

Let’s start by looking at the HTML side of this functionality. Listing 1 shows the JavaScript that is needed to accept the data from the PDF and how to embed the PDF inside the HTML page.

In listing 1, the PDF is treated as an object. If we give it an id, for instance myPdf, we can create a variable using document.getElementById(“myPdf”). We use this variable in #1 to accept data from the PDF and, in #2, to send data to the PDF.

HTML-to-PDF communication

The JavaScript method sendToPdf() is triggered when the end user clicks the button in the HTML form. It passes a message to the PDF object. This message is of an array of String values. It will only be accepted if the PDF is “disclosed” and if there’s a message handler in place. The JavaScript code shown in listing 2 was added as an Open action to the document javascript.pdf.

Listing 2 post_from_html.js

[code lang=”java”]this.disclosed = true; 1
if (this.external && this.hostContainer) { 2
function onMessageFunc( stringArray ) { 3
var name = this.myDoc.getField("personal.name"); 3
var login = this.myDoc.getField("personal.loginname"); 3
try{ 3
name.value = stringArray[0]; 3
login.value = stringArray[1]; 3
} 3
catch(e){ 3
onErrorFunc(e); 3
} 3
} 3
function onErrorFunc( e ) { 4
console.show(); 4
console.println(e.toString()); 4
} 4
try {
if(!this.hostContainer.messageHandler); 5
this.hostContainer.messageHandler = new Object(); 5
this.hostContainer.messageHandler.myDoc = this; 5
this.hostContainer.messageHandler.onMessage = onMessageFunc; 5
this.hostContainer.messageHandler.onError = onErrorFunc; 5
this.hostContainer.messageHandler.onDisclose = function(){ 5
return true; 5
}; 5
}
catch(e){
onErrorFunc(e);
}
}
1 Disclose the PDF document
2 Check if the PDF is opened in a host container
3 Function that handles incoming messages
4 Function that handles errors
5 Create the message handler[/code]

JavaScript communication between documents is only possible if the document is disclosed (#1). You also need to check if the document is opened in an external window. If so, you need access to the host container (#2). In this case, the host container is the web browser.
Note

The hostContainer property doesn’t work on the Mac OS system. Because of that limitation, this example may not work for you or for a segment of your customers.

The code in #5 creates a message handler for the host container. It also defines a function to handle messages (#3) and errors (#4). The method postMessage() in #2 of listing 2 passes a message to the onMessage method of the messageHandler. In our implementation, the first entry in the message array is used to fill in the field personal.name, the second entry to fill in the field personal.loginname. Now, let’s take a look at the communication in the opposite direction.

PDF-to-HTML communication

When an end user clicks on the “POST TO HTML” button in the PDF document, the following JavaScript snippet is executed.

Listing 3 post_to_html.js

[code lang=”java”]if(this.hostContainer) {
var names = new Array();
names[0] = this.getField("personal.name").value.toString();
names[1] = this.getField("personal.loginname").value.toString();
try{
this.hostContainer.postMessage(names);
}
catch(e){
app.alert(e.message);
}
}[/code]

In listing 3, we check if the PDF is opened in a host container. If it is, we put the values we want to transmit to the HTML JavaScript in an array and we use the postMessage() method of the host container. This message will only be accepted if there’s a message handler in place for the PDF object. This message handler is created in the createMessageHandler() (#1 in listing 1) that was triggered when the HTML page was loaded; see the onLoad attribute of the body tag. This method is similar to what we did in listing 2. The onMessage:function accepts an array of String values. In our implementation, these values are used to fill out fields in the HTML form.

This example was a little bit out of scope for learning about iText. You’ll find more information about HTML-to-PDF communication (and vice-versa) in the “JavaScript for Acrobat API Reference” (http://www.adobe.com/devnet/acrobat/javascript.html).

Summary

In this article, we’ve used a PDF form to demonstrate how to establish the communication between a PDF document and its host container, the web browser. We’ve sent messages back and forth between an HTML page and a PDF document.

Filed Under: Java Tagged With: iText, PDF

Creating a Raw Image in iText

April 23, 2011 by Krishna Srinivasan Leave a Comment

This article is based on iText in Action, Second Edition, published on October, 2010. It is being reproduced here by permission from Manning Publications. Manning publishes MEAP (Manning Early Access Program,) eBooks and pBooks. MEAPs are sold exclusively through Manning.com. All pBook purchases include free PDF, mobi and epub. When mobile formats become available all customers will be contacted and upgraded. Visit Manning.com for more information. [ Use promotional code ‘java40beat’ and get 40% discount on eBooks and pBooks ]

also read:

  • Java Tutorials
  • Java EE Tutorials
  • Design Patterns Tutorials
  • Java File IO Tutorials

Creating a Raw Image

Introduction

An image consists of a series of pixels. Each pixel has a color. The color value of the sequence of pixels can be stored in a byte array, and the byte array can be compressed, for instance, using zlib/flate compression. Figure 1 shows some images that were created byte per byte.

Figure 1 Images built using raw image data

Let’s have a look at the source code that was used to create these images.

Listing 1 RawImage.java

[code lang=”java”](int i = 0; i < 256; i++) A
gradient[i] = (byte) i; A
Image img1 = Image.getInstance(256, 1, 1, 8, gradient); 1
img1.scaleAbsolute(256, 50);
document.add(img1);
byte cgradient[] = new byte[256 * 3]; B
for (int i = 0; i < 256; i++) {
cgradient[i * 3] = (byte) (255 – i); C
cgradient[i * 3 + 1] = (byte) (255 – i); D
cgradient[i * 3 + 2] = (byte) i; E
}
Image img2 = Image.getInstance(256, 1, 3, 8, cgradient); 2
img2.scaleAbsolute(256, 50);
document.add(img2);
Image img3 = Image.getInstance(16, 16, 3, 8, cgradient); 3
img3.scaleAbsolute(64, 64);
document.add(img3);

A Create image data
1 Create a DeviceGray/8 bpc image
B Create image data
C Red
D Green
E Blue
2 Create an RGB/8bpc image
3 Create an RGB/8bpc image[/code]

We’re creating three images in listing 1. The first one has 256 × 1 pixels. The colorspace is DeviceGray (1 component), and we’re using 8 bits per component (#1). When we create the image data, we let the color value vary from 0 to 255. This produces the gradient from black to white in figure 1. (Note that we scaled the height of the image.)

For the second and third images, we use three components with 8 bits per component. This means that we’ll need 256 × 3 bytes to describe an image that consists of 256 pixels. We use the image data to create an image of 256 × 1 pixels (#2), and to create an image of 16 × 16 pixels. Note that this image uses the DeviceRGB color space. If you create an image with four components, you’re working in the DeviceCMYK color space. The getInstance() method used in listing 1 also accepts an extra parameter to define a transparency range.

What we’re doing manually in this example, is done automatically with GIF, PNG, BMP, and some TIFF images internally. These bytes are added to a zipped stream using the zlib/flate algorithm, except for some TIFF and PNG images that are CCITT-encoded.

Summary

In this article, we discussed creating an image manually or byte per byte. This operation is done automatically with GIF, PNG, BMP, and some TIFF images.

Filed Under: Java Tagged With: iText, PDF

Follow Us

  • Facebook
  • Pinterest

As a participant in the Amazon Services LLC Associates Program, this site may earn from qualifying purchases. We may also earn commissions on purchases from other retail websites.

JavaBeat

FEATURED TUTORIALS

Answered: Using Java to Convert Int to String

What is new in Java 6.0 Collections API?

The Java 6.0 Compiler API

Copyright © by JavaBeat · All rights reserved