我正在尝试(拼命)通过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
答案 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");
}