Last week I blogged about sending the contents of a RichText field (including images and attachments) as an HTML mail. Today’s task was related: get the contents of a RichText item as HTML, knowing that the contents can be stored in the item as either MIME or standard RichText.
With the wrapDocument() function I showed you last week you can easily get MIME contents as HTML. It turns out that with some small changes you can use the same method to let Domino convert ‘standard’ RichText into HTML. You probably saw this in action already: create a document with RichText in the Notes client and edit it on the web. What’s new is that this method allows you to do it programmatically.
The trick is in the DominoRichTextItem class: it has two constructors to create it: using either a MIMEEntity or by giving it a RichTextItem. That’s all the info I needed to update my previous function:
/* * Wraps a lotus.domino.Document as a com.ibx.xsp.model.domino.wrapped.DominoDocument, including a RichText item * * @param doc document to be wrapped * * @param richTextItemName name of the rich text item containing standard RichText or MIME contents that need to be wrapped */ private static DominoDocument wrapDocument(final Document doc, final String richTextItemName) throws NotesException {</code> DominoDocument wrappedDoc = null; Database db = doc.getParentDatabase(); //disable MIME to RichText conversion db.getParent().setConvertMIME(false); //wrap the lotus.domino.Document as a lotus.domino.DominoDocument //see http://public.dhe.ibm.com/software/dw/lotus/Domino-Designer/JavaDocs/DesignerAPIs/com/ibm/xsp/model/domino/wrapped/DominoDocument.html wrappedDoc = DominoDocument.wrap(doc.getParentDatabase().getFilePath(), doc, null, null, false, null, null); //see http://public.dhe.ibm.com/software/dw/lotus/Domino-Designer/JavaDocs/DesignerAPIs/com/ibm/xsp/model/domino/wrapped/DominoRichTextItem.html DominoRichTextItem drti = null; Item itemRT = doc.getFirstItem(richTextItemName); if (null != itemRT) { if (itemRT.getType() == Item.RICHTEXT) { //create a DominoRichTextItem from the RichTextItem RichTextItem rt = (RichTextItem) itemRT; drti = new DominoRichTextItem(wrappedDoc, rt); } else if (itemRT.getType() == Item.MIME_PART) { //create a DominoRichTextItem from the Rich Text item that contains MIME MIMEEntity rtAsMime = doc.getMIMEEntity(richTextItemName); drti = new DominoRichTextItem(wrappedDoc, rtAsMime, richTextItemName); } } wrappedDoc.setRichTextItem(richTextItemName, drti); return wrappedDoc; }
Using this function you can wrap any document and get the HTML from a RichText item:
View view = db.getView("someview"); Document doc = view.getFirstDocument(); DominoDocument ddoc = wrapDocument(doc, "Body"); DominoRichTextItem drti = ddoc.getRichTextItem("Body"); String html = drti.getHTML(); System.out.println(html);
Great tip ! Will this give me the same result as when using : http://////?OpenField ?
Url should be : http://server/db.nsf/view/docunid/RTfieldname?OpenField
Didn’t know of that command, so I just tested it. The result looks the same, with one exception. Domino adds font tags to the generated HTML. If you use the ?openField command, a <font size=”2″> is added, with my function it adds a <font size=”1″>. I guess this is probably a default size that’s set somewhere.
In my application I’ve also added a XSnippet written by Steve Pridemore to remove all font tags from the generated HTML. That uses a Java library call JSoup to parse the HTML. It depends on your requirements of course, but I would recommend to use that approach.
Thanks for your feedback ! I’ll have a look at it 🙂
Would that also work in a standalone Java app? Or only inside an XPages app or OSGi plug-in?
Good question. It requires access to the com.ibm.xsp classes so I think it will only work in XPages or an OSGi plugin. Not 100% sure though.
Thank you for the informative article. I am trying to run this as a standalone JAVA application as below.
private static DominoDocument wrapDocument(final Document doc, final String richTextItemName) throws NotesException {
Session session = NotesFactory.createSession();
Database db = session.getDatabase(“”, “/tmp/sample.nsf”);
DocumentCollection dc = db.getAllDocuments();
Document doc = dc.getFirstDocument();
DominoDocument wrappedDoc = null;
Database db = doc.getParentDatabase();
//disable MIME to RichText conversion
db.getParent().setConvertMIME(false);
wrappedDoc = DominoDocument.wrap(doc.getParentDatabase().getFilePath(), doc, null, null, false, null, null);
DominoRichTextItem drti = null;
However I get the following errors thrown from DominoDocument.wrap() method.
Thread name in wrapDocument Thread-5
java.lang.IllegalStateException: NotesContext not initialized for the thread
at com.ibm.domino.xsp.module.nsf.NotesContext.getCurrent(NotesContext.java:123)
at com.ibm.xsp.model.domino.wrapped.DominoDocument.(DominoDocument.java:240)
at com.ibm.xsp.model.domino.wrapped.DominoDocument.wrap(DominoDocument.java:123)
at RunNote.wrapDocument(RunNote.java:620)
at RunNote.runNotes(RunNote.java:111)
at lotus.domino.NotesThread.run(Unknown Source)
Exception in thread “Thread-5” java.lang.ExceptionInInitializerError
at java.lang.J9VMInternals.initialize(J9VMInternals.java:222)
at RunNote.wrapDocument(RunNote.java:638)
at RunNote.runNotes(RunNote.java:111)
at lotus.domino.NotesThread.run(Unknown Source)
Caused by: java.lang.IllegalStateException: No Factories configured for this Application – typically this is because a context listener is not setup in your web.xml.
A typical config looks like this;
org.apache.myfaces.webapp.StartupServletContextListener
at javax.faces.FactoryFinder.getFactory(FactoryFinder.java:84)
at com.ibm.xsp.application.ApplicationEx._getInstance(ApplicationEx.java:96)
at com.ibm.xsp.application.ApplicationEx.getInstance(ApplicationEx.java:75)
at com.ibm.xsp.model.domino.wrapped.DominoRichTextItem.(DominoRichTextItem.java:2037)
at java.lang.J9VMInternals.initializeImpl(Native Method)
at java.lang.J9VMInternals.initialize(J9VMInternals.java:200)
… 3 more
Am I missing something here? Appretiate your thoughts on this.
Hi,
Thanks. And sorry, but I can’t help you with that. I only tried it from an XPages context.
Maybe there’s something in the org.openntf.domino library that can help you.
Hi Mark.
How do sections and tabbed tables, created by the end user in the RT field, translate to the HTML: are they “usable”?
I’m about to attack that part, looking at various options including your code, Genii’s AppFidelity and other tricks like the ?OpenField and reading the HTML out of the URL. I don’t even know where to start!!!
Haven’t tested that myself: so go ahead 🙂 The code only reads what the server generates, so I hope it works for you.
Hi Ben,
Where you able to get HTML of Tabbed Table from RT Field.If yes,Please provide ur code here.
I have similar kind of requirement.
Thanks & Regards,
Hi Joseph,
Were you able to get the output?
I’m working on similar standalone java application where I need to get Table which I created in Document but when I use doc.getItemValueString(EmailRoboConstant.BODY),It just shows the Cell’s Text value.Table format gets disappear.
Please help.
Thanks & Regards,
Manisha