1
votes

I’m trying to use the POI Bean (from POI 4 XPages) to generate a Word document with content from an XPage. I have added and configured a REST service as per the example in the POI Example database.

var template = poiBean.buildResourceTemplateSource(null,"YourFile.docx");
var lstBM = new java.util.ArrayList();
var jce:CategoryFields = new CategoryFields();
var doc = currentDocument.getDocument(true);
var retOutput1 = jce.getCategoryField1(doc);
var retOutput2 = jce.getCategoryField2(doc);
var doc:NotesDocument = currentDocument.getDocument();
var Field1 = retOutput1;
var Field2 = retOutput2;
lstBM.add(poiBean.buildDocumentBookmark("Field1", retOutput1));
lstBM.add(poiBean.buildDocumentBookmark("Field2", retOutput2));
var result = poiBean.processDocument2Stream(template, lstBM);
if (result == null) {
print("?????");
}
return new java.io.ByteArrayInputStream(result.toByteArray()) 

I would like to now create a response document which contains the result of the above code in a richtext field. My preference is to place the necessary code (I imagine SSJS) in the onClick event of a button. However, from a button I don’t know how to get a handle on the output of the REST service. Does anyone know how I could do this ?

I've changed the code suggested below as follows:

package AZGPackage;
import java.io.*;
import java.util.List;
import lotus.domino.*;
import biz.webgate.dominoext.poi.beans.PoiBean;
import biz.webgate.dominoext.poi.component.data.ITemplateSource;

public class MimeMaker {

private final PoiBean poiBean;
private final String templateName;
private String resultName;

public MimeMaker(PoiBean poiBean, String templateName, String resultName) {
    this.poiBean = poiBean;
    this.templateName = templateName;
}

public void renderToDocument(Session s, Document doc) throws NotesException {

    ITemplateSource template = poiBean.buildResourceTemplateSource(null,this.templateName);
    List lstBM = new java.util.ArrayList();
    CategoryFields jce = new CategoryFields();
    String retOutput1 = jce.getCategoryField1(doc);
    String retOutput2 = jce.getCategoryField2(doc);

    lstBM.add(poiBean.buildDocumentBookmark("Fachkompetenz", retOutput1));
    lstBM.add(poiBean.buildDocumentBookmark("Arbeitsverhalten", retOutput2));
    ByteArrayOutputStream result = poiBean.processDocument2Stream(template, lstBM);

    // Do the mime
    s.setConvertMime(false);
    MIMEEntity emailRoot = doc.createMIMEEntity("Body");
    MIMEEntity emailRootChild = emailRoot.createChildEntity();

    MIMEHeader emailHeader = emailRootChild.createHeader("Content-Disposition");
    emailHeader.setHeaderVal("attachment; filename=\"" + resultName + "\"");
    InputStream is = new ByteArrayInputStream(result.toByteArray());
    Stream stream = s.createStream();
    stream.setContents(is);
    emailRootChild.setContentFromBytes(stream, "x-vnd/ms-office-docx", MIMEEntity.ENC_IDENTITY_BINARY);

    s.setConvertMime(true);

   }
 }

However after calling:

var mimeMaker = new AZGPackage.MimeMaker(poiBean, "YourFile.docx", "someFile.docx");
mimeMaker.renderToDocument(session, currentDocument.getDocument(true));

I get the error:

Script interpreter error, line=3, col=11: Error calling method 'renderToDocument(lotus.domino.local.Session, lotus.domino.local.Document)' on java class 'AZGPackage.MimeMaker'

2
For starters: don't import class.*; be specific. Then remove the throws NotesException and handle the Exception inside your code. If the field Body already exists the createMIMEEntity will fail. You could change the return type from void to String and return "success" or the error text - nice for checking.stwissel
Thanks, I've made the changes you suggest. The code fails at the line InputStream is = new ByteArrayInputStream(result.toByteArray()); with the error java.lang.NullPointerExceptionuser1358852
The line ByteArrayOutputStream result = poiBean.processDocument2Stream(template, lstBM); seems not to work but I can't figure out why.user1358852
create a public static void main(String[] args) {stwissel
Thanks, I'll try this when I have time. Compared to Lotus Notes, working with MS Word in XPages is so much more difficult :-(user1358852

2 Answers

2
votes

Create a Java class, roughly like this:

public class MimeMaker {

private final PoiBean poiBean;
private final String templateName;

public MimeMaker(PoiBean poiBean, String templateName, String resultName) {
    this.poiBean = poiBean;
    this.templateName = templateName;
}

public void renderToDocument(Session s, Document doc) {
    Template template = poiBean.buildResourceTemplateSource(null,this.templateName);
    Collection lstBM = new java.util.ArrayList();
    CategoryFields jce = new CategoryFields();
    String retOutput1 = jce.getCategoryField1(doc);
    String retOutput2 = jce.getCategoryField2(doc);

    lstBM.add(poiBean.buildDocumentBookmark("Field1", retOutput1));
    lstBM.add(poiBean.buildDocumentBookmark("Field2", retOutput2));
    ByteArrayOutputStream result = poiBean.processDocument2Stream(template, lstBM);

    // Do the mime
    s.setConvertMime(false);
    MIMEEntity emailRoot = emailDocument.createMIMEEntity("Body");
    MIMEEntity emailRootChild = emailRoot.createChildEntity();

    MIMEHeader emailHeader = emailRootChild.createHeader("Content-Disposition");
    emailHeader.setHeaderVal("attachment; filename=\"" + resultName + "\"");
    InputStream is = new ByteArrayInputStream(result.toByteArray());
    Stream stream = s.createStream();
    stream.setContents(is);
    emailRootChild.setContentFromBytes(stream, "x-vnd/ms-office-docx", MIMEEntity.ENC_IDENTITY_BINARY);

    s.setConvertMime(true);
   }
 }

You need to fix the data types (I just typed into Notepad), but you get the gist. You then can go into the button and do:

    var mimeMaker = new com.acme.MimeMaker(poiBean, "YourFile.docx", "someFile.docx");
    mimeMaker.renderToDocument(session, currentDocument.getDocument(true);

Let us know how it goes

0
votes

I solved this issue using the docx4j library. I thinks it's a much better option than Apache POI. Check out http://www.docx4java.org