Getting HTML from any RichText item

HTML_logoLast 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);

12 thoughts to “Getting HTML from any RichText item”

    1. 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.

    1. 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.

  1. 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.

  2. 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!!!

    1. Haven’t tested that myself: so go ahead 🙂 The code only reads what the server generates, so I hope it works for you.

    2. 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,

  3. 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

Comments are closed.