【问题标题】:Birt: access content of dataset from beforeFactoryBirt:从 beforeFactory 访问数据集的内容
【发布时间】:2015-01-15 15:53:17
【问题描述】:

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

手头的任务是从链接库创建设计元素并将它们放置在网格的某个单元格中。除了“将它们放在网格的某个单元格中”部分之外,一切正常。

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

例如:在body上放了一个网格(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 天)我的成功率为零(如 null)。

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

问候, 马古茨

【问题讨论】:

    标签: javascript birt


    【解决方案1】:

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

    主要限制是:不能直接使用 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");
    }
    

    【讨论】:

    • 我忘了提,我从 xml 文件中检索所有数据。因此,您的代码(看起来很有希望)不适用于我的情况。但是,我尝试使代码适应我的情况,请参阅我自己的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多