BIRT 使用xml动态数据源总结

fengzhizi0 2009-05-25

因为系统需要,添加报表功能,瞄上了birt,学习之,入门教程看了一大堆,还好,多种数据源支持,对于sql还没精通,看着一大堆sql还有点犯难,所以,xml数据源成了我的首选,仔细研究之下,发现原来birt提供的初级功能原来很少,报表经常需要替换数据源来显示其不同的内容,而传统的设置xml数据源只是事前指定好xml文件,或url,google了一下,基本没有发现可用的例子,郁闷之,自己琢磨了一周几乎,更郁闷的是其实问题早有了答案,就载在acegi的权限控制之上一直未看到胜利的曙光下面把自己动态修改xml数据源的成功发上来我用的是webwork,其他用户请酌情修改相应参数

这个是用来view报表的action需要传入的参数是

reban.reportName=报表文件的文件名

rbean.xmlDataUrl=报表xmldatasourceurl,可以是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);
	}

}
robin 写道

使用方法

在浏览器中输入url

http://localhost:8800/stat/birtviewer.action?rbean.reportName=index.rptdesign&rbean.xmlDataUrl=http://localhost:8800/stat/armrptxml.action?reporter.id=008a81b61c30d47e011c4f446718001b

对报表熟悉的人应该知道这个方法

相关推荐