关于birt报表输出时的JDBC连接跟Script Data Source连接的设置
一个完整的birt的报表设计过程包括两部分:一是设计报表;二是运行和生成报表;
一、报表设计生成
报表设计生成就是生产一个报表的模板,及.rptdesign格式的文件(实际是一个xml文件的生成),这个过程包括了以下几个步骤:
1)生成数据源(datasource);2)生成数据集(dataset);3)生成报表设计
这个过程有很多的例子,比如birt官方的例子如下:
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("OFFICECODE");
al.add("CITY");
al.add("COUNTRY");
de.buildReport(al, "From Offices" );
}
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",
"org.eclipse.birt.report.data.oda.sampledb.Driver" );
dsHandle.setProperty( "odaURL", "jdbc:classicmodels:sampledb" );
dsHandle.setProperty( "odaUser", "ClassicModels" );
dsHandle.setProperty( "odaPassword", "" );
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:/work/libs/birt-runtime-2_2_2/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("new_report.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( "sample.rptdesign" ); //$NON-NLS-1$
designHandle.close( );
System.out.println("Finished");
}catch (Exception e){
e.printStackTrace();
}
}
就可以生成一个名字叫“sample.rptdesign”的报表设计。
二是运行和生成报表
是利用birt的engine运行上面设计好的报表模板,生成所需要的报表输出。这个过程主要分成:1)生成报表引擎(ReportEngine);2)设置输出方式(pdf、word、ppt等);3)运行报表,生成输出文件。
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.logging.Level;
import org.eclipse.birt.core.exception.BirtException;
import org.eclipse.birt.core.framework.Platform;
import org.eclipse.birt.report.engine.api.EngineConfig;
import org.eclipse.birt.report.engine.api.EngineException;
import org.eclipse.birt.report.engine.api.IReportEngine;
import org.eclipse.birt.report.engine.api.IReportEngineFactory;
import org.eclipse.birt.report.engine.api.IReportRunnable;
import org.eclipse.birt.report.engine.api.IRunAndRenderTask;
import org.eclipse.birt.report.engine.api.PDFRenderOption;
public class MyReportCreator {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
EngineConfig config = new EngineConfig();
config.setBIRTHome("D:/work/libs/birt-runtime-2_2_2/ReportEngine");
// Explicitly set up the stand-alone application
// Start the platform for a non-RCP application.
try {
Platform.startup(config);
} catch (BirtException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
IReportEngineFactory factory = (IReportEngineFactory) Platform
.createFactoryObject(IReportEngineFactory.EXTENSION_REPORT_ENGINE_FACTORY);
// Set up writing images or charts embedded in HTML output.
// HTMLRenderOption ho = new HTMLRenderOption();
// ho.setImageHandler(new HTMLCompleteImageHandler());
// config.setEmitterConfiguration(HTMLRenderOption.OUTPUT_FORMAT_HTML, ho);
PDFRenderOption option = new PDFRenderOption();
option.setOutputFormat("pdf");
try {
OutputStream output = new FileOutputStream("./a.pdf");
option.setOutputStream(output);
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
// config.setEmitterConfiguration(PDFRenderOption.OUTPUT_FORMAT_PDF, option);
config.setLogConfig("d:/work", Level.WARNING);
// Create the engine.
IReportEngine engine = factory.createReportEngine(config);
String designName = "./SimpleReport.rptdesign";
IReportRunnable runnable = null;
try {
runnable = engine.openReportDesign(designName);
} catch (EngineException e) {
System.err.println("Design " + designName + " not found!");
engine.destroy();
System.exit(-1);
}
// Get the value of a simple property.
IRunAndRenderTask task = engine.createRunAndRenderTask(runnable);
task.setParameterValue("Param1", new String("the input string."));
task.setParameterValue("Param2", 6);
task.setRenderOption(option);
try {
task.run();
} catch (EngineException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
task.close();
}
}
这里需要特别关注的是,在实际工程中应用JDBC或者scriptedDataSource时,输出报表时,会报一个找不到driver或自定义的类的错误,此时的解决方法是:
对于JDBC连接,要把相应的driver的jar包放在{$birt_runtime_home}\ReportEngine\plugins\org.eclipse.birt.report.data.oda.jdbc_2.2.2.r22x_v20071206
例如:D:\work\libs\birt-runtime-2_2_2\ReportEngine\plugins\org.eclipse.birt.report.data.oda.jdbc_2.2.2.r22x_v20071206
对于scriptedDataSource要设置EngineConfig的一个环境变量:
this.reportConfig.getAppContext().put(EngineConstants.APPCONTEXT_CLASSLOADER_KEY, YourClass.class.getClassLoader());
例如:
this.reportConfig.getAppContext().put(EngineConstants.APPCONTEXT_CLASSLOADER_KEY, com.tkxing.htmlparser.buss.report.model.SingleStockDataReportModel.class.getClassLoader());