2015-01-15 12 views
0

我試圖(絕望地)通過beforeFactory中的腳本訪問數據集的內容。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

回答

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"); 
} 
+0

我忘了提,我檢索一個XML文件的所有數據。因此,你的代碼(就像它看起來那樣有保證)不適用於我的情況。然而,我試圖將代碼適用於我的情況,請參閱我自己的答案。 – maggutz 2015-01-20 08:50:18