toxi.in.process

Tuesday, August 21, 2007

Creating weblinks in PDF with iText

Mr. LennyJPG pinged me this morning asking about creating hyperlinks in PDFs generated with Processing. After some digging through the iText javadocs and reading various tutorials it became obvious that Processing's PGraphicsPDF class had to be modified to give us access to the wrapped PdfContentByte instance so that the hyperlink magic can happen. My modified version of Processing's PDF library can be downloaded from here (jar) and there (source). The .jar has to be placed in the /libraries/pdf/library folder inside the Processing root, but please make sure to keep a backup of the original.

The demo below is briefly showing how to create weblinks (here: to various del.icio.us users) and how to position these on the page. All should be pretty self-explanatory. Finally, here's an example PDF generated with this demo.

/**
* iText/Processing PDF weblink demo
* Builds a number of links on the fly and
* positions them randomly on the page.
*
* CAUTION: This demo requires a modified version of
* Processing's PGraphicsPDF class
*
* @author: info at toxi dot co dot uk
*/
import processing.pdf.*;
import com.lowagie.text.*;
import com.lowagie.text.pdf.*;

void setup() {
pageSize(com.lowagie.text.PageSize.A6,false,JAVA2D);
PGraphicsPDF pdf=(PGraphicsPDF)beginRecord(PDF,"test"+(System.currentTimeMillis()/1000)+".pdf");

// draw something in the background
for(int i=0; i < height; i+=10) {
line(0,0,width,i);
line(width,height,0,i);
}

try {
// build hyperlinks for these del.icio.us users
String[] users=new String[] {
"adm",
"blackbeltjones",
"d3",
"garuda",
"golan",
"hahakid",
"jbleecker",
"lennyjpg",
"reas",
"toxi"
};

for(int i=0; i < users.length; i++) {
// java colours are normalized 0.0 .. 1.0
Color linkCol = new Color(random(1), random(1), random(1));
Chunk c=new Chunk(users[i],FontFactory.getFont(FontFactory.HELVETICA, 14, com.lowagie.text.Font.UNDERLINE, linkCol));
c.setBackground(new Color(0,0,0),5,5,5,5);
c.setAnchor("http://del.icio.us/"+users[i]);
// this is using a hacked version of PGraphicsPDF to get access to the PDF content
PdfContentByte cb=pdf.getContent();
ColumnText ct = new ColumnText(cb);
float x=random(width-100);
float y=random(height-100);
ct.setSimpleColumn(new Phrase(c), x,y, x+100, y+50, 16, Element.ALIGN_CENTER);
ct.go();
}
}
catch(Exception e) {
e.printStackTrace();
}
endRecord();
}

// see link below for more info about this method:
// http://www.toxi.co.uk/blog/2007/07/specifying-pdf-page-size-in-processing.htm
void pageSize(com.lowagie.text.Rectangle r, boolean isLandscape, String renderer) {
if (isLandscape) {
size((int)r.top(),(int)r.right(),renderer);
}
else {
size((int)r.right(),(int)r.top(),renderer);
}
}

6 Comments:

At 8/21/2007 8:05 PM, lenny said...

ha! wow! damn, you're pretty fast.
now that's great. exactly what i was looking for. really great toxi, thanks a lot. you're the man :)

 
At 8/23/2007 6:47 PM, patrik said...

Exception in thread "Thread-2" java.lang.UnsupportedClassVersionError: Bad version number in .class file
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:620)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:124)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:260)
at java.net.URLClassLoader.access$100(URLClassLoader.java:56)
at java.net.URLClassLoader$1.run(URLClassLoader.java:195)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:268)



this is what p55 output after play it.
i already changed the .jar file but won't work

 
At 8/23/2007 7:25 PM, toxi said...

Argh... I'm using the latest version of Java which creates class files which are incompatible with older versions of Java (pre 1.5). I've just recompiled the library and replaced the file on the server. Have another go please and do let me know if that helped. Thanks!

 
At 8/23/2007 9:20 PM, patrik said...

i will as soon as i can!

 
At 8/23/2007 9:25 PM, patrik said...

it work great !
nice job !
all the best

 
At 8/28/2007 11:51 PM, Marius said...

That's a useful addition.

I've been looking for a way to do grouping or layers in PDF, but haven't found a good way to do it. Any ideas?

 

Post a Comment

Links to this post:

Create a Link

<< Home