如何以编程方式为BIRT报告设置数据源?
问题描述:
我有一个连接到我们测试数据库的BIRT报告。在生产环境中,我想提供一个由容器通过jndi提供的数据源。如何以编程方式为BIRT报告设置数据源?
如何以给定报告的编程方式设置数据源?
...
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元素。
答
在运行时只设置数据源将会产生问题,因为数据集绑定到单个数据源,并且您的报表控件将绑定到特定的数据集。每次报告运行时,尝试构建自己的层次结构都非常困难。
您可以参数化数据源定义的所有方面,使您的设计可以在所有环境中使用。编辑数据源时,请查看左侧的属性绑定分组。这应该给你足够的灵活性,使你的数据源更加便携。您可以为JDBC URL元素或运行时JNDI配置文件指定运行时参数。
希望这会有所帮助。
答
您可以为数据库连接字符串创建报告参数。
然后,设置JNDI URL下的数据源 - >属性绑定 - > JNDI URL,如:PARAMS [ “数据库”]值
(其中, “数据库” 的报告参数的名称)
答
看看下面的代码,你可能会在运行时提供数据源方面的帮助。
对于我的要求,它工作正常。
我从一些网站得到这个不记得。
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();
}
}
}
答
我喜欢亚当斯的做法。 下面是我们如何做到这一点:
/*
* 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());
}
}
}
在此,“丽萨” IST他的数据源的名字,我们想在运行时更改。 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());