Creating pdf from dxl containing richtext picture attachments

Hi

I’m thinking about exporting a few notes documents to pdf. The documents contain richtext items containing pasted images and I want them to be available as images in the pdf file after export.

I was thinking of using the following procedure:

  • export documents to dxl

  • transform dxl to xsl-fo using xslt

  • generator pdf from xsl-fo using Apache FOP

I haven’t tried this yet, but I don’t see why it can’t work. But I’m having a bit of trouble seeing how I can convert richtext items of type to an image in the xsl-fo.

Has anyone done this?

Must I use fo:instream-foreign-object for this? If so, then how? An example would be nice.

Appreciate any help or advice.

Subject: Creating pdf from dxl containing richtext picture attachments

look at this post

Subject: RE: Creating pdf from dxl containing richtext picture attachments

From what it seems, it would have been wiser for Lotus to implement a ConvertNotesbitmapsToPNG or ConvertNotesbitmapsToJPEG property. I’m not sure that Apache Batik (and therefore Apache FOP) can rasterize GIF input at present. (I imagine that these Apache products are probably what the majority of people are using). However, they seem to work for JPG and PNG input.

I can get it working using something like:

fo:instream-foreign-object

<svg:svg width=“200” height=“200” viewBox=“0 0 200 200” xml:space=“preserve”>

<svg:image width=“60” height=“60” xlink:href="data:image/jpg;base64,

R0lGODlhDAAMAIAAAMwAM8DAwCH5BAEAAAEALAAAAAAMAAwAQAIZjI8HmwvhGnOUQoZi3Xdr

/z3ZhCkk+KBLAQA7 etc…"/>

</svg:svg>

</fo:instream-foreign-object>

but not with gif.

Subject: RE: Creating pdf from dxl containing richtext picture attachments

My understanding is that the DXL developers were/are planning ConvertNotesbitmapsToJPEG functionality but it hasn’t make it into any point release at this time.

Possibly Dick (Annicchiarico) may be abe to shed additional insight.

Regards

Wayne

Subject: RE: Creating pdf from dxl containing richtext picture attachments

Much of the current DXL work is aimed towards improving the robustness of what is already there in 6.x. Other threads in this and the Partner forum have pointed out that in some areas, most notably certain design elements but not limited to that, the 6.x implementation isn’t quite robust enough for the ultimate goal of lossless round-tripping or re-importing notes (replacing or updating) after making changes with DXL. Our feeling was that the base, though quite solid in 6.x, needed to be improved upon some more before completely focusing on new features. Which is a long way of saying that we haven’t yet got around to doing the notesbitmap to jpeg (or png or whatever) translations. But we are listening to what people want and making a list for 7.0 and future releases, so let us know where you want DXL to go and the relative importance (on just a low, medium, high scale or something simple) of each proposed feature.

How many others think other translations, other than the existing notesbitmap to gif, are desirable in the Exporter. Which formats are desired? Are there known workarounds, such as open source translators from gif to the desired formats?

Subject: Working solution!

Hi

I got something working so I just thought I’d contribute the framework code of what I did to get there for anyone interested.

First off, I doubt this will ever work as a domino agent etc. The solution needs access to a Base64 encoder and decoder. I’m using the classes in the sun.misc.* package on sun’s j2se 1.4.2_01, but these aren’t distributed as a part of the supported java API. I don’t think they are available as part of the domino JVM, but I haven’t looked.

Step 1)

Generate the xml from a document(s) containing a pasted image in a richtext field. I’m using a notes 6.5 client to generate the xml. The code to do this looks something like:

DxlExporter exporter = session.createDxlExporter();

exporter.setConvertNotesBitmapsToGIF(true);

String dxl = exporter.exportDxl(collection);

Step 2)

Create a XSL stylesheet to process the xml. It traverses the domino items in the exported dxl to get to the binary gif file image dump. This data is base64 encoded. Now, I doubt that there is a base64 decoder available in standard XSLT so that leads us to step 3.

Step 3)

Extend the standard XSLT functionality. I’m using Apache Xalan for XSL transforming. You have to create a java class that takes the xml image data from the domino dxl and send it to your java class. My java class does the following:

  • get input from caller

  • base64 decode the input

  • transform the result to png

  • base64 encode the result

  • return the encoded result to the XSLT caller

This actually isn’t as hard as it may seem. It’s looks something like this (comments welcome):


String s;

BASE64Encoder encoder = new BASE64Encoder();

BASE64Decoder decoder = new BASE64Decoder();

ByteArrayInputStream input = new ByteArrayInputStream(s.getBytes());

ByteArrayOutputStream output = new ByteArrayOutputStream();

ByteArrayOutputStream decoded = new ByteArrayOutputStream();

decoder.decodeBuffer(input, decoded);

input.close();

BufferedImage im = ImageIO.read(new ByteArrayInputStream(decoded.toByteArray()));

ByteArrayOutputStream png = new ByteArrayOutputStream();

ImageIO.write(im, “png”, png);

encoder.encode(new ByteArrayInputStream(png.toByteArray()), output);

return output.toString();


Extending Apache Xalan is easier than I initially thought, but you may want to try it with something simpler before attempting this. You also have to set a few things in your XSL so that the transformer can find your java code. You also have to make sure the class is available for your JVM. I did this by packaging the class in a jar file a putting it in my jvm\lib\ext directory so it is available to Xalan-J.

Step 4)

Your output from of the transform must be using XSL-FO if you want to use FOP to create a pdf.

I used the fo:instream-foreign-object when adding the resulting image dump back to the xml. It looks something like this:

fo:instream-foreign-object

<svg:svg width=“{$width}” height=“{$height}”>

<svg:image width="{$width}" height="{$height}"> 

  <xsl:attribute name="xlink:href">

    <xsl:value-of select="concat('data:image/png;base64,', mystuff:png(.))"/>

  </xsl:attribute>

</svg:image>

</svg:svg>

</fo:instream-foreign-object>

Is there a better way of doing this than using the xlink:href attribute? Comments welcome!

Anyway, here my call to the XSLT extension is mystuff:png(). You set this up at the top of you stylesheet (see extension-element-prefixes, Apache Xalan docs).

Step 5)

Transform the resulting xml (with included image data) using Apache FOP to create a pdf file.

In summary, to do this you need to have some knowledge of:

java

xml namespaces

xslt

xsl-fo

some svg

Good luck!

Subject: RE: Working solution!

Hi Lee

I would like to extract pasted picture and save it to disk from a notes document. Your solution could work for me; Could it be possible to have an example of your XSL and your complete agent to do this ? I suppose I don’t need xsl-fo to do it ?

Thanks in advance

Iphana

Subject: RE: Working solution!

Well, first off and as I said in my posting, Java Agents don’t have access to the base64 decoder that comes with the sun JRE distribution so I didn’t create this as an agent. You would have to download a base64 decoder to get it working as an agent.

The relevant parts of the java XSLT extension and XSL stylesheet were posted in my posting. The Xalan documentation will help you to figure out how to use them together.

Just remember to set the DXLExporter option to export images as gif. You can then use XSL to navigate you way to the richtext/par/picture/gif element.

Subject: Working solution - Creating pdf from dxl containin…

Some extra comments to help anyone trying to undertake the richtext to pdf conversion.

The framework Lee outlines in his post is an excellent blue-print for carrying out the conversion. You can do this conversion using an agent as well as using the Domino servlet container. In both cases however, you will not be able to use the ImageIO as it is a J2se 1.4 API. However, you could use either Graphics2D or Jimi to carryout the image conversions. The Base64 decoding and encoding can be done with the sun.misc.* or ibm.misc.* package which is somewhere in the distribution packages with Domino.

The next issue you will come up against which Lee raised in a separate post (http://www-10.lotus.com/ldd/nd6forum.nsf/DateAllThreadedweb/3c6e7498c931996385256e33007f537f?OpenDocument) is that XML4j.jar shipped with Domino uses redistributed org.w3c.dom classes which are old versions not supporting DOM2 which FOP requires for the transformation. How you approach this is obviously up to you. I decompiled and compared the distribution with Domino against a DOM2 source and decided to create a new XML4j.jar with six (updated) org.w3c.dom classes which FOP requires. The six classes are:

DOMImplementation

Document

Node

Attr

Element

NamedNodeMap

From what I saw comparing the two distributions, all of the classes from the new distribution contain the fields and methods contained in the older Domino distribution. NB: You cannot use a new distribution of XML4j from IBM as it doesn’t contain classes which Domino requires. So unless you make this change to XML4j you won’t be able to carryout the transformation using Domino’s JVM.

You can carry out the process in pre 6.0.2 but you would have to use the Notes CAPI to work with the decoded bitmap.

If you are able to use 6.5.1 you can place the the jars in the jvm\lib\ext and specify the JavaUserClasses ini setting too. You also have the added benefit of being able to programatically create links to the your .pdfs anywhere in a richtext field on a Notes document.

In testing I have found that the process works perfectly fine invoked as a agent (cycling through hundreads of docs) or invoked as a servlet. Although the in-memory process does use a lot of memory (as stated on Apache’s site) and without raising the heap size the VM did run out of memory, especially on large images.

Subject: Steve: XML4J question…

  • You mention that one can’t replace XML4J because there is required Domino stuff in there and the transformation won’t work. This doesn’t bother me; I’m trying to transform data in a file (persuant to importing to create documents) and Domino will only do that on data in fields. You are correct, Domino’s XSL is broken by replacing XML4J, but that fixes other things I require.- My question is, do you know of anything else that might be broken because of replacing XML4J with a non-paleolithic version? DXL import, for instance?

  • When you repackaged XML4J, I presume you simply un-jarred the contents and re-jarred them with the indicated classes replaced? Perhaps I should try that to get Xalan/Xerces to work, just to be sure I’m not breaking something besides Domino’s XSLT? So far I’ve not gotten Apache’s XSLT to play nicely with Domino, but I’m in the process of scouring the forum and found your post, so I thought I’d pause here a moment. (grin)

  • Just curious. Thanks for your time…

Subject: Ima Tard…

  • Sort of.- This method of repackaging XML4J works like a charm, which I didn’t doubt, but I went one step further and added the original XML4J classes to xerces.jar, and put that new XML4J.jar into the Notes directory. It appears to work fine, and gives full Axis functionality while retaining Domino’s XSL processing. Thanks for putting me onto this, Steve!

  • The 'tard part is that Domino’s XSL does in fact work on files. It’s just not obvious because “help” isn’t particulary well organized to provide information the various overloaded constructors for the XSLTInputSource class, and when it’s not right the compiler consistently complains because it’s not getting a Node object. But if it’s done right, a file can in fact be used as both the input and the output to the Domino XSL engine, and all is well.

  • So I was wrong on that score. Hope I didn’t lead anyone astray…

Subject: RE: Creating pdf from dxl containing richtext picture attachments

Yes, I had seen it.

However, it doesn’t really change anything does it? I mean, I still have to process the binary dump in some way or other. That’s what I’m wondering about. How do you get the binary dump to be an image in xsl-fo?

Subject: RE: Creating pdf from dxl containing richtext picture attachments

Use base64 decoder.See this discussion

Subject: Creating pdf from dxl containing richtext picture attachments

Have you gone through this tutorial:

It may give you the info that you need.

Subject: RE: Creating pdf from dxl containing richtext picture attachments

Thanks for the link, but I don’t think the tutorial covers what I’m thinking of. It speaks of SVG images. However, the image attachments in the dxl richtext field are binary printouts by the looks of things.