Birt:从beforeFactory访问数据集的内容

时间:2015-01-15 15:53:17

标签: javascript birt

我正在尝试(拼命)通过beforeFactory中的脚本访问数据集的内容。

手头的任务是从链接库中创建设计元素,并将它们放在网格的某个单元格中。一切都很好,除了"将它们放在网格的某个单元格中.-部分。

有关要创建哪个元素及其放置位置的信息可在数据集(dsDesignInformation)中获得,该数据集包含三列:targetRow,targetColumn,targetContent。 targetContent包含一个字符串,用于查找库中的元素。

例如:在主体上放置一个网格(grdMasterGrid),有两行和两列。如果dsDesignInformation包含类似(1,1," testObjectName")的行,我想创建元素" testObject"从链接库中将它放在我的grdMasterGrid的第1行和第1列的交集中。

创建和放置元素的代码:

importPackage(org.eclipse.birt.report.model.api);

var myLibraryHandle = reportContext.getDesignHandle().getLibrary("myLibraryName");
var myElementFactory = reportContext.getDesignHandle().getElementFactory();

// should be the objectname as defined in the dsDesignInformation 
var myTargetElementHandle = myLibraryHandle.findElement("testObjectName");
var myCreatedElementHandle = myElementFactory.newElementFrom(myTargetElementHandle , "someUniqueElementName");

var myMasterGridHandle = reportContext.getDesignHandle().findElement("grdMasterGrid");
// should be target coordinates as defined in dsDesignInformation 
var myTargetCellHandle= myMasterGridHandle.getCell(1,1);
myTargeCellHandle.getContent().add(myCreatedElementHandle);

当与硬编码目标信息一起使用时,它就像魅力一样,并放置在报表设计的beforeFactory中。

但我需要访问dsDesignInformation的内容并将它们传递给上面的脚本。到目前为止(4天),我的成功为零(如无效)。

我很高兴有关该主题的任何帮助或想法。

此致 maggutz

1 个答案:

答案 0 :(得分:0)

可以做到这一点,但有一些严格的限制。

主要限制是:您无法直接使用DataSource和DataSet。 相反,您必须复制它们并使用副本。 不要问我这是为什么,因为我不知道。但是我在尝试的几小时和几天里学到了很难......

下一个限制是:遗憾的是,您无法访问报表参数值。如果您的查询在没有参数的情况下工作,这不是问题。 否则,您无论如何都必须找到一种方法来访问参数值。例如,根据报表在应用程序中的集成方式,您可以尝试在调用BIRT之前将值写入appContext。

以下是工作代码的片段(在beforeFactory事件中),向您展示如何解决此限制:

importPackage( Packages.org.eclipse.birt.report.model.api );
importPackage(Packages.org.eclipse.birt.data.engine.api);
importPackage(Packages.org.eclipse.birt.report.model.api);
importPackage(Packages.org.eclipse.birt.data.engine.api.querydefn);
importPackage(Packages.org.eclipse.birt.data.engine.core);
importPackage( Packages.org.eclipse.birt.report.model.api );

var myconfig = reportContext.getReportRunnable().getReportEngine().getConfig();
var de = DataEngine.newDataEngine( myconfig, null );

var dsrc = reportContext.getDesignHandle().findDataSource("lisa");
// This is the existing data source.

var odaDataSource = new OdaDataSourceDesign( "Test Data Source" );
// We create a new DataSource which is only to be used in this event

// Now we copy the relevant properties from the existing DataSource to the new one.
var dbUrl = dsrc.getProperty("odaURL").toString();
var dbUsr = dsrc.getProperty("odaUser").toString();
var dbPwd = dsrc.getProperty("odaPassword").toString();
var dbDrv = dsrc.getProperty("odaDriverClass").toString();
odaDataSource.setExtensionID( "org.eclipse.birt.report.data.oda.jdbc" );
odaDataSource.addPublicProperty( "odaURL", dbUrl );
odaDataSource.addPublicProperty( "odaDriverClass", dbDrv);
odaDataSource.addPublicProperty( "odaUser", dbUsr );
odaDataSource.addPublicProperty( "odaPassword", dbPwd );        

// log.info("odaURL=" + dbUrl); // Only if you have a logging framework at hand

// Now create a new DataSet and set its query etc.
// I suppose that it is possible to copy the properties from an existing DataSet instead.
//  However, I didn't try that.
var odaDataSet = new OdaDataSetDesign( "Test Data Set" );
odaDataSet.setDataSource( odaDataSource.getName() );
odaDataSet.setExtensionID( "org.eclipse.birt.report.data.oda.jdbc.JdbcSelectDataSet" );

// This is the SQL query (in my application).
// You'll have to modify this as needed.
odaDataSet.setQueryText( " select STEDA.TEDA_ID, STBST.LANGTEXT" +
                     " from STEDA, STBST" +
                     " where STEDA.ZUSATZ_1 = 'MATRIX'" +
                     " and STBST.TBST_ID = STEDA.TEDA_ID"); 

// Tell the DataEngine about the new objects.
de.defineDataSource( odaDataSource );
de.defineDataSet( odaDataSet );

// Now execute the query:
// This seems overly complicated, but hey: it works.
var queryDefinition = new QueryDefinition( );
queryDefinition.setDataSetName( odaDataSet.getName() );
queryDefinition.setAutoBinding(true);
var pq = de.prepare( queryDefinition );
var qr = pq.execute( null );

rowcount=0;     
var elementFactory = reportContext.getDesignHandle().getElementFactory()
var ri = qr.getResultIterator( );       

// Our application is using the query to generate a layout structure 
// into an (already existing) placeholder element "Layout MATRIX".
var containerGrid = reportContext.getDesignHandle().findElement("Layout MATRIX");

// Iterate through the query results
while (  ri.next( ) )
{
    // get the actual values of the query output columns
    var tedaId = ri.getString("TEDA_ID");
    var langtext = ri.getString("LANGTEXT");
    // log.info("langtext: " + langtext);
    rowcount++;

    // Do something with the current result row.
    ... myModifyLayout(containerGrid, tedaId, langtext); ...
}

// Cleanup
ri.close( );
qr.close( );
de.shutdown( );

// You may want to save the modified design file while developing.
// That way you can check the mresults in the Report Designer.
if (false) {
    reportContext.getDesignHandle().saveAs("c:/temp/modified.rptdesign");
}