How to create a webi document using Java Report Engine SDK

This post describes the typical workflow required to create a new Webi document in BO XI 3.1. You can download the compete code here . We will consider an example how to create a simple Webi document based on Island Resorts Marketing universe that will display resort service and revenue from that service for US.

Connect to CMS and initialize engine

The first steps are establishing connection with the CMS and initializing the report engine.

// Connect to CMS
ISessionMgr sessionMgr = CrystalEnterprise.getSessionMgr();
IEnterpriseSession enterpriseSession = sessionMgr.logon(user, pass, host, auth);
// Initialize Webi report engine
ReportEngines reportEngines = (ReportEngines) enterpriseSession.getService("ReportEngines");
ReportEngineType type = ReportEngines.ReportEngineType.WI_REPORT_ENGINE;
ReportEngine reportEngine = (ReportEngine) reportEngines.getService(type);

Create new document

First, we perform CMS query to find the universe Island Resorts Marketing (which is one of the standard sample universes). (It is assumed that the universe exists).

IInfoStore infoStore = (IInfoStore) enterpriseSession.getService("InfoStore");
String unvQuery = "select * from CI_APPOBJECTS where SI_KIND = 'Universe'" 
                + " and SI_NAME='Island Resorts Marketing'";
IInfoObjects infoObjects = (IInfoObjects) infoStore.query(unvQuery);
IInfoObject infoObject = (IInfoObject)infoObjects.get(0);

Second, we actually create a new document.

DocumentInstance documentInstance = reportEngine.newDocument("UnivCUID="+infoObject.getCUID());

After this we initialize some helper variables. Data Provider and Query describe the same (query). Query is an interface to add objects and conditions, change properties such as maximum row retrieved etc. Data Provider is an interface primarily to run, purge the query etc. Data Source is equivalent to universe. If universe has multiple queries but each query use the same universe, there will be only one data source. Data Source provides all available objects in the universe.

DataProviders dps = documentInstance.getDataProviders();
DataProvider dataProvider = dps.getItem(0);
Query query = dataProvider.getQuery();
DataSource dataSource = dataProvider.getDataSource();

Build the query

First, we add a couple of objects available in the data source – Service and Revenue.

DataSourceObjects objects = dataSource.getClasses();
query.addResultObject(objects.getChildByName("Service"));
query.addResultObject(objects.getChildByName("Revenue"));

Second, we construct the condition. The condition is County='US'.

ConditionContainer container = query.createCondition(LogicalOperator.AND);
ConditionObject conditionObject = container.createConditionObject(objects.getChildByName("Country"));
FilterCondition filterCondition = conditionObject.createFilterCondition(Operator.EQUAL);
filterCondition.createFilterConditionConstant("US");

The last step is to run queries.

dataProvider.runQuery();

Build the layout

So now we can add report to the document structure. Report container contains report header, body and footer.

ReportStructure reportStructure = documentInstance.getStructure();
ReportContainer reportContainer = reportStructure.createReport("My Report");
ReportBody reportBody = reportContainer.createReportBody();

In this example, we create a table with the two fields.

ReportBlock reportBlock = reportBody.createBlock();
ReportDictionary reportDictionary = documentInstance.getDictionary();
BlockAxis hAxis = reportBlock.getAxis(TableAxis.HORIZONTAL);
hAxis.addExpr(reportDictionary.getChildByName("Service"));
hAxis.addExpr(reportDictionary.getChildByName("Revenue"));

When the report is created from scratch, all default values are blanks and zeros so it is important to set the necessary attributes such as color, font, width.

SimpleTable simpleTable = (SimpleTable)reportBlock.getRepresentation();
CellMatrix bodyMatrix = simpleTable.getBody();
CellMatrix headerMatrix = simpleTable.getHeader(null);
CellMatrix[] matrices = new CellMatrix[]{bodyMatrix, headerMatrix}; 
for (CellMatrix matrix : matrices) {
   for (int i=0; i<matrix.getColumnCount();++i)
   {   
      TableCell cell = matrix.getCell(0, i);
      Attributes attributes = cell.getAttributes();
      if (matrix == bodyMatrix) {
         attributes.setBackground(Color.white);
         attributes.setForeground(Color.black);
      } else {
         attributes.setBackground(new Color(81, 117,185));
         attributes.setForeground(Color.white);
      }
      SimpleBorder border = (SimpleBorder)attributes.getBorder();
      border.setSize(BorderSize.NONE);				
      cell.setAttributes(attributes);
      Font font = cell.getFont();
      font.setName("Arial");
      font.setSize(10);
      cell.setFont(font);
      Alignment alignment = cell.getAlignment();
      alignment.setHorizontal(HAlignmentType.LEFT);
      cell.setAlignment(alignment);
      cell.setWidth(50);
   }
}

The final step is to apply format. It is important. If you miss this step, the report structure will not be modified.

documentInstance.applyFormat();

Save the document

The final step is to save the document to a folder. We can use function
DocumentInstance.saveAs(title, int destinationFolderId, categories, personalCategories, overwrite)

First we need to find the destination folder id. We assume that the folder Report Samples exists.

String folderQuery = "select * from CI_INFOOBJECTS where SI_KIND = 'Folder'"
                   + " and SI_NAME='Report Samples'";
infoObjects = (IInfoObjects) infoStore.query(folderQuery);
infoObject = (IInfoObject)infoObjects.get(0); 
int folderId = infoObject.getID();

Now we can save the document with title "Test".

documentInstance.saveAs("Test", folderId, null, null, true);
documentInstance.closeDocument();

Hope this helps.