BIRT 使用xml動態數據源總結

因爲系統需要,添加報表功能,瞄上了birt,學習之,入門教程看了一大堆,還好,多種數據源支持,對於sql還沒精通,看着一大堆sql還有點犯難,所以,xml數據源成了我的首選,仔細研究之下,發現原來birt提供的初級功能原來很少,報表經常需要替換數據源來顯示其不同的內容,而傳統的設置 xml數據源只是事前指定好xml文件,或url,google了一下,基本沒有發現可用 的例子,鬱悶之,自己琢磨了一週幾乎,更鬱悶的是其實問題早有了答案,就載在acegi的權限控制之上一直未看到勝利的曙光下面把自己動態修改xml數據源的成功發上來我用的是webwork,其他用戶請酌情修改相應參數
這個是用來view報表的action 需要傳入的參數是
reban.reportName = 報表文件的文件名
rbean.xmlDataUrl = 報表xml datasource url ,可以是stream,或xxx.xml之類的,輸入瀏覽器能顯示xml即可
BirtReportViewer.java

package com.morepower.controller.birt;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;

import org.eclipse.birt.report.engine.api.EngineConstants;
import org.eclipse.birt.report.engine.api.HTMLRenderOption;
import org.eclipse.birt.report.engine.api.HTMLServerImageHandler;
import org.eclipse.birt.report.engine.api.IHTMLRenderOption;
import org.eclipse.birt.report.engine.api.IRenderOption;
import org.eclipse.birt.report.engine.api.IReportEngine;
import org.eclipse.birt.report.engine.api.IReportRunnable;
import org.eclipse.birt.report.engine.api.IRunAndRenderTask;
import org.eclipse.birt.report.model.api.DataSourceHandle;
import org.eclipse.birt.report.model.api.ElementFactory;
import org.eclipse.birt.report.model.api.OdaDataSetHandle;
import org.eclipse.birt.report.model.api.OdaDataSourceHandle;
import org.eclipse.birt.report.model.api.ReportDesignHandle;
import org.eclipse.birt.report.model.api.TableHandle;
import org.eclipse.birt.report.model.api.activity.SemanticException;


import com.morepower.controller.AbstractAction;
import com.morepower.util.BirtEngine;
import com.morepower.view.BirtReporterBean;
import com.opensymphony.webwork.ServletActionContext;
import com.opensymphony.webwork.interceptor.ServletRequestAware;

public class BirtReportViewer extends AbstractAction implements
ServletRequestAware {
/**
*
*/
private static final long serialVersionUID = 1L;
private static String REPORT_DIR = "birt-reportors";
private static String REPORT_IMAGE_DIR = "images";
private IReportEngine birtReportEngine = null;
private HttpServletRequest request;
private BirtReporterBean rbean;
private InputStream reportStream;
private static String DATASOURCE_NAME = "DataSource";
private static String DATASET_NAME = "DataSet";
private static String QueryText = "";

public InputStream getReportStream() {
return this.reportStream;
}

@Override
public String execute() throws Exception {
// get report name and launch the engine
// resp.setContentType("text/html");
// resp.setContentType( "application/pdf" );
// resp.setHeader ("Content-Disposition","inline; filename=test.pdf");
String reportName = rbean.getReportName();
ServletContext sc = ServletActionContext.getServletContext();
birtReportEngine = BirtEngine.getBirtEngine(sc);
IReportRunnable design = birtReportEngine.openReportDesign(sc
.getRealPath(java.io.File.separator + REPORT_DIR)
+ java.io.File.separator + reportName);

ReportDesignHandle report = (ReportDesignHandle) design
.getDesignHandle();

// 只是動態更換數據源即可,不需改變報表的其他結構
// 暫時不支持動態創建表格

// create task to run and render report
buildReport(report);
IRunAndRenderTask task = birtReportEngine
.createRunAndRenderTask(design);
task.getAppContext().put(EngineConstants.APPCONTEXT_CLASSLOADER_KEY,
BirtReportViewer.class.getClassLoader());

// set output options
HTMLRenderOption options = new HTMLRenderOption();
options.setImageHandler(new HTMLServerImageHandler());
options.setImageDirectory(sc.getRealPath(java.io.File.separator
+ REPORT_IMAGE_DIR));
options.setBaseImageURL(request.getContextPath()
+ java.io.File.separator + REPORT_IMAGE_DIR);
options.setOutputFormat(HTMLRenderOption.OUTPUT_FORMAT_HTML);
options.setOption(IRenderOption.HTML_PAGINATION, Boolean.TRUE);
options.setOption(IHTMLRenderOption.MASTER_PAGE_CONTENT, new Boolean(
true));

// options.setOutputFormat(HTMLRenderOption.OUTPUT_FORMAT_PDF);
options.setOption(HTMLRenderOption.HTML_ENABLE_METADATA, Boolean.FALSE);
ByteArrayOutputStream bout = new ByteArrayOutputStream();
//String renderstr = bout.toString("utf-8");
options.setOutputStream(bout);
task.setRenderOption(options);

/*
* 另外一種方案,直接在action中構造inputStream 對像,但這樣
* 可能導致你的報表viewer與具體業務類耦合!
* task.getAppContext().put(org.eclipse.datatools.enablement.oda.xml.Constants.APPCONTEXT_INPUTSTREAM,
reportStream);
task.getAppContext().put(org.eclipse.datatools.enablement.oda.xml.Constants.APPCONTEXT_CLOSEINPUTSTREAM,
Boolean.TRUE);*/

// run report

task.run();
task.close();
reportStream = new ByteArrayInputStream(bout.toByteArray());

return SUCCESS;
}

/**
* 清除原有的數據源
*/
protected void clearDataSource(ReportDesignHandle designHandle) {
//DataSourceHandle dsh = designHandle.findDataSource(DATASOURCE_NAME);
//dsh.drop();
int count = designHandle.getDataSources().getCount();

try {
for (int i = 0; i < count; i++)
designHandle.getDataSources().drop(i);
} catch (SemanticException e) {
log.error(e);
e.printStackTrace();
}
}

/**
* 清除原有的數據集
*/
protected void clearDataSet(ReportDesignHandle designHandle) {
getQueryText(designHandle);
int count = designHandle.getDataSets().getCount();
try {
for (int i = 0; i < count; i++)
designHandle.getDataSets().drop(i);
} catch (SemanticException e) {
log.error(e);
e.printStackTrace();
}
}

/**
*
*/
protected void getQueryText(ReportDesignHandle designHandle) {
QueryText = (String) designHandle.getDataSets().get(0).getProperty(
"queryText");
}

protected void buildReport(ReportDesignHandle designHandle) {
try {
ElementFactory designFactory = designHandle.getElementFactory();
buildDataSource(designFactory, designHandle);
buildDataSet(designFactory, designHandle);
TableHandle table = (TableHandle) designHandle.getBody().get(0);
table.setDataSet(designHandle.findDataSet(DATASET_NAME));

} catch (SemanticException e) {
log.error(e);
e.printStackTrace();
}

}

protected void buildDataSource(ElementFactory designFactory,
ReportDesignHandle designHandle) throws SemanticException {
clearDataSource(designHandle);
OdaDataSourceHandle dsHandle = designFactory.newOdaDataSource(
DATASOURCE_NAME,
"org.eclipse.birt.report.data.oda.xml" );
/*dsHandle.setProperty( "odaDriverClass",
"com.mysql.jdbc.Driver" );
dsHandle.setProperty( "odaURL", "jdbc:mysql://localhost/stat" );
dsHandle.setProperty( "odaUser", "root" );
dsHandle.setProperty( "odaPassword", "" );*/
dsHandle.setProperty("FILELIST", rbean.getXmlDataUrl());
designHandle.getDataSources().add(dsHandle);
}

protected void buildDataSet(ElementFactory designFactory,
ReportDesignHandle designHandle) throws SemanticException {

clearDataSet(designHandle);
OdaDataSetHandle dsHandle = designFactory.newOdaDataSet( DATASET_NAME,
//"org.eclipse.birt.report.data.oda.jdbc.JdbcSelectDataSet" );
/* OdaDataSetHandle dsHandle = designFactory.newOdaDataSet(DATASET_NAME,*/
"org.eclipse.birt.report.data.oda.xml.dataSet");
dsHandle.setPrivateDriverProperty("XML_FILE", rbean.getXmlDataUrl());
dsHandle.setPrivateDriverProperty("MAX_ROW", "-1");
dsHandle.setQueryText(QueryText);
dsHandle.setDataSource(DATASOURCE_NAME);
designHandle.getDataSets().add(dsHandle);

}

@Override
public void setServletRequest(HttpServletRequest arg0) {
request = arg0;

}

@Override
public void destory() {
BirtEngine.destroyBirtEngine();
}

public BirtReporterBean getRbean() {
return rbean;
}

public void setRbean(BirtReporterBean rbean) {
this.rbean = rbean;
}

@Override
public void initilize() {
try {
log.info("報表系統初始化中............");
BirtEngine.initBirtConfig();
REPORT_DIR = BirtEngine.getBirtReportorProperty("report_dir");
REPORT_IMAGE_DIR = BirtEngine
.getBirtReportorProperty("report_image_dir");
DATASOURCE_NAME = "DataSource";
DATASET_NAME = "DataSet";
} catch (Exception e) {
e.printStackTrace();
log.error(e);
}
}

}



BirtEngine.java

package com.morepower.util;
import java.io.InputStream;
import java.io.IOException;
import java.util.Properties;
import java.util.logging.Level;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.birt.report.engine.api.EngineConfig;
import org.eclipse.birt.report.engine.api.IReportEngine;
import javax.servlet.*;
import org.eclipse.birt.core.framework.PlatformServletContext;
import org.eclipse.birt.core.framework.IPlatformContext;
import org.eclipse.birt.core.framework.Platform;
import org.eclipse.birt.core.exception.BirtException;
import org.eclipse.birt.report.engine.api.IReportEngineFactory;

public class BirtEngine {
private static IReportEngine birtEngine = null;
private static Properties configProps = new Properties();
private final static String configFile = "BirtConfig.properties";
protected final static Log log = LogFactory.getLog(BirtEngine.class);
public static synchronized void initBirtConfig() {

loadEngineProps();
}

public static synchronized IReportEngine getBirtEngine(ServletContext sc) {
if (birtEngine == null) {
EngineConfig config = new EngineConfig();
if (configProps != null) {
String logLevel = configProps.getProperty("logLevel");
Level level = Level.OFF;
if ("SEVERE".equalsIgnoreCase(logLevel)) {
level = Level.SEVERE;
} else if ("WARNING".equalsIgnoreCase(logLevel)) {
level = Level.WARNING;
} else if ("INFO".equalsIgnoreCase(logLevel)) {
level = Level.INFO;
} else if ("CONFIG".equalsIgnoreCase(logLevel)) {
level = Level.CONFIG;
} else if ("FINE".equalsIgnoreCase(logLevel)) {
level = Level.FINE;
} else if ("FINER".equalsIgnoreCase(logLevel)) {
level = Level.FINER;
} else if ("FINEST".equalsIgnoreCase(logLevel)) {
level = Level.FINEST;
} else if ("OFF".equalsIgnoreCase(logLevel)) {
level = Level.OFF;
}

config.setLogConfig(configProps.getProperty("logDirectory"),
level);
}
//sc.getRealPath("")+java.io.File.separator+configProps.getProperty("engine_home")
config.setEngineHome("");
IPlatformContext context = new PlatformServletContext(sc);
log.info(context.getPlatform());
config.setPlatformContext(context);

try {
Platform.startup(config);
} catch (BirtException e) {
e.printStackTrace();
}

IReportEngineFactory factory = (IReportEngineFactory) Platform
.createFactoryObject(IReportEngineFactory.EXTENSION_REPORT_ENGINE_FACTORY);
birtEngine = factory.createReportEngine(config);

}
return birtEngine;
}

public static synchronized void destroyBirtEngine() {
if (birtEngine == null) {
return;
}
birtEngine.shutdown();
Platform.shutdown();
birtEngine = null;
}

public Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}

private static void loadEngineProps() {
try {
// Config File must be in classpath
ClassLoader cl = Thread.currentThread().getContextClassLoader();
InputStream in = cl.getResourceAsStream(configFile);
configProps.load(in);
in.close();

} catch (IOException e) {
e.printStackTrace();
}

}
public static String getBirtReportorProperty(String key){
return configProps.getProperty(key);
}

}


[quote="robin"]
使用方法
在瀏覽器中輸入url
http://localhost:8800/stat/birtviewer.action?rbean.reportName=index.rptdesign&rbean.xmlDataUrl=http://localhost:8800/stat/armrptxml.action?reporter.id=008a81b61c30d47e011c4f446718001b
[/quote]
對報表熟悉的人應該知道這個方法
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章