如何以编程方式为BIRT报告设置数据源?

我有一个BIRT报告连接到我们的测试数据库。 在生产环境中,我想提供一个由容器通过jndi提供的数据源。

如何以编程方式为给定报告设置数据源?

... IReportRunnable design = birtEngine.openReportDesign ( new File ( properties.getProperty ( "reportPath" ), report + ".rptdesign" ).getAbsolutePath () ); IRunAndRenderTask task = birtEngine.createRunAndRenderTask ( design ); PDFRenderOption options = new PDFRenderOption (); options.setOutputFormat ( PDFRenderOption.OUTPUT_FORMAT_PDF ); options.setOutputStream ( out ); task.setRenderOption ( options ); for ( Entry entry : parameters.entrySet () ) { task.setParameterValue ( entry.getKey (), entry.getValue () ); } task.run (); task.close (); ... 

我想我必须修改design但另一方面task有一个方法setDataSource但看起来有点像我必须提供一些xml dom元素。

查看以下代码,您可以在运行时提供数据源方面获得一些帮助。

根据我的要求,它工作正常。

我从一些网站得到这个不记得了。

 import java.io.IOException; import java.util.ArrayList; import org.eclipse.birt.core.framework.Platform; import org.eclipse.birt.report.model.api.CellHandle; import org.eclipse.birt.report.model.api.DataItemHandle; import org.eclipse.birt.report.model.api.DesignConfig; import org.eclipse.birt.report.model.api.ElementFactory; import org.eclipse.birt.report.model.api.IDesignEngine; import org.eclipse.birt.report.model.api.IDesignEngineFactory; import org.eclipse.birt.report.model.api.LabelHandle; import org.eclipse.birt.report.model.api.OdaDataSetHandle; import org.eclipse.birt.report.model.api.OdaDataSourceHandle; import org.eclipse.birt.report.model.api.PropertyHandle; import org.eclipse.birt.report.model.api.ReportDesignHandle; import org.eclipse.birt.report.model.api.RowHandle; import org.eclipse.birt.report.model.api.SessionHandle; import org.eclipse.birt.report.model.api.StructureFactory; import org.eclipse.birt.report.model.api.TableHandle; import org.eclipse.birt.report.model.api.activity.SemanticException; import org.eclipse.birt.report.model.api.elements.structures.ComputedColumn; import com.ibm.icu.util.ULocale; /** * Dynamic Table BIRT Design Engine API (DEAPI) demo. */ public class DECreateDynamicTable { ReportDesignHandle designHandle = null; ElementFactory designFactory = null; StructureFactory structFactory = null; public static void main( String[] args ) { try { DECreateDynamicTable de = new DECreateDynamicTable(); ArrayList al = new ArrayList(); al.add("USERNAME"); al.add("COUNTRY"); de.buildReport(al, "From GTM_REPORT_APP_USER" ); } catch ( IOException e ) { // TODO Auto-generated catch block e.printStackTrace(); } catch ( SemanticException e ) { // TODO Auto-generated catch block e.printStackTrace(); } } void buildDataSource( ) throws SemanticException { OdaDataSourceHandle dsHandle = designFactory.newOdaDataSource( "Data Source", "org.eclipse.birt.report.data.oda.jdbc" ); dsHandle.setProperty( "odaDriverClass", "oracle.jdbc.driver.OracleDriver" ); dsHandle.setProperty( "odaURL", "jdbc:oracle:thin:@xeon:1521:ora9i" ); dsHandle.setProperty( "odaUser", "AIMS_GTMNE" ); dsHandle.setProperty( "odaPassword", "AIMS_GTMNE" ); designHandle.getDataSources( ).add( dsHandle ); } void buildDataSet(ArrayList cols, String fromClause ) throws SemanticException { OdaDataSetHandle dsHandle = designFactory.newOdaDataSet( "ds", "org.eclipse.birt.report.data.oda.jdbc.JdbcSelectDataSet" ); dsHandle.setDataSource( "Data Source" ); String qry = "Select "; for( int i=0; i < cols.size(); i++){ qry += " " + cols.get(i); if( i != (cols.size() -1) ){ qry += ","; } } qry += " " + fromClause; dsHandle.setQueryText( qry ); designHandle.getDataSets( ).add( dsHandle ); } void buildReport(ArrayList cols, String fromClause ) throws IOException, SemanticException { //Configure the Engine and start the Platform DesignConfig config = new DesignConfig( ); config.setProperty("BIRT_HOME", "D:/Softwares/Frame Works - APIs-Tools/birt-runtime-2_6_1/birt-runtime-2_6_1/ReportEngine"); IDesignEngine engine = null; try{ Platform.startup( config ); IDesignEngineFactory factory = (IDesignEngineFactory) Platform.createFactoryObject( IDesignEngineFactory.EXTENSION_DESIGN_ENGINE_FACTORY ); engine = factory.createDesignEngine( config ); }catch( Exception ex){ ex.printStackTrace(); } SessionHandle session = engine.newSessionHandle( ULocale.ENGLISH ) ; try{ //open a design or a template designHandle = session.openDesign("D:/tempBirtReport/test.rptdesign"); designFactory = designHandle.getElementFactory( ); buildDataSource(); buildDataSet(cols, fromClause); TableHandle table = designFactory.newTableItem( "table", cols.size() ); table.setWidth( "100%" ); table.setDataSet( designHandle.findDataSet( "ds" ) ); PropertyHandle computedSet = table.getColumnBindings( ); ComputedColumn cs1 = null; for( int i=0; i < cols.size(); i++){ cs1 = StructureFactory.createComputedColumn(); cs1.setName((String)cols.get(i)); cs1.setExpression("dataSetRow[\"" + (String)cols.get(i) + "\"]"); computedSet.addItem(cs1); } // table header RowHandle tableheader = (RowHandle) table.getHeader( ).get( 0 ); for( int i=0; i < cols.size(); i++){ LabelHandle label1 = designFactory.newLabel( (String)cols.get(i) ); label1.setText((String)cols.get(i)); CellHandle cell = (CellHandle) tableheader.getCells( ).get( i ); cell.getContent( ).add( label1 ); } // table detail RowHandle tabledetail = (RowHandle) table.getDetail( ).get( 0 ); for( int i=0; i < cols.size(); i++){ CellHandle cell = (CellHandle) tabledetail.getCells( ).get( i ); DataItemHandle data = designFactory.newDataItem( "data_"+(String)cols.get(i) ); data.setResultSetColumn( (String)cols.get(i)); cell.getContent( ).add( data ); } designHandle.getBody( ).add( table ); // Save the design and close it. designHandle.saveAs( "D:/tempBirtReport/test.rptdesign" ); //$NON-NLS-1$ designHandle.close( ); System.out.println("Finished"); }catch (Exception e){ e.printStackTrace(); } } } 

您可以为数据库连接字符串创建报告参数。

然后,在数据源 – >属性绑定 – > JNDI URL下设置JNDI URL,如下:params [“Database”]。value
(其中“数据库”是报告参数的名称)

在运行时仅设置数据源将是有问题的,因为数据集绑定到单个数据源,然后报表上的控件绑定到特定数据集。 每次报告运行时,尝试构建自己的层次结构都非常棘手。

您可以参数化数据源定义的所有方面,使您的设计可以在所有环境中移植。 编辑数据源时,请查看左侧的属性绑定分组。 这应该为您提供足够的灵活性,使您的数据源更具可移植性。 您可以为JDBC URL元素或运行时JNDI配置文件指定运行时参数。

希望这可以帮助。

我喜欢亚当斯的做法。 我们是这样做的:

  /* * Change the data sources in the .rptdesign */ void changeDataSource(ElementFactory designFactory, ReportDesignHandle designHandle, String userConnect) throws SemanticException { SlotHandle datasources = designHandle.getDataSources(); SlotIterator iter = (SlotIterator) datasources.iterator(); while (iter.hasNext()) { DesignElementHandle dsHandle = (DesignElementHandle) iter.next(); if (dsHandle instanceof OdaDataSourceHandle && dsHandle.getName().equals("lisa")) { log.debug("changeDataSource: Changing datasource " + dsHandle.getName() + " new url=" + getLisaDbUrl()); dsHandle.setProperty("odaDriverClass", "oracle.jdbc.driver.OracleDriver"); dsHandle.setProperty("odaURL", getLisaDbUrl()); dsHandle.setProperty("odaUser", getLisaUser()); dsHandle.setProperty("odaPassword", getLisaPassword()); } else { log.debug("changeDataSource: Ignoring DS " + dsHandle.getName()); } } } 

在这里,“lisa”是我们想要在运行时更改的数据源的名称。 get …函数返回“生产”运行时所需的值。

这对我有用。 我得到了上下文,并从上下文得到了dataSource并将连接传递给Birt报告,如下所示

  Context initialContext = new InitialContext(); if ( initialContext == null){ System.out.println("JNDI problem. Cannot get InitialContext."); } DataSource datasource = (DataSource)initialContext.lookup("java:/datasources/SAMPLE"); task.getAppContext().put("OdaJDBCDriverPassInConnection", datasource.getConnection());