我有一个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<String, Object> entry : parameters.entrySet () )
{
task.setParameterValue ( entry.getKey (), entry.getValue () );
}
task.run ();
task.close ();
...
我想我必须修改design
,但另一方面task
有一个方法setDataSource
,但看起来有点像我必须提供一些xml dom元素。
答案 0 :(得分:6)
请查看以下代码,您可以在运行时提供数据源方面获得一些帮助。
根据我的要求,它可以正常工作。
我从某个网站得到这个不记得。
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();
}
}
}
答案 1 :(得分:3)
您可以为数据库连接字符串创建报告参数。
然后,在数据源下设置JNDI URL - &gt;属性绑定 - &gt; JNDI URL,as:params [“Database”]。value
(其中“数据库”是报告参数的名称)
答案 2 :(得分:2)
答案 3 :(得分:1)
我喜欢亚当斯的做法。 以下是我们的工作方式:
/*
* 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());
}
}
}
在这里,&#34;丽莎&#34;是我们想要在运行时更改的数据源的名称。 get ...函数返回&#34; production&#34;所需的值。运行时间。
答案 4 :(得分:1)
这对我有用。我得到了上下文并从上下文获取了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());