📄 report.java
字号:
/*
* Created on 2006-6-8
*
* TODO To change the template for this generated file go to
* Window - Preferences - Java - Code Style - Code Templates
*/
package net.excel.report;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.excel.report.Logger;
import net.excel.report.base.IReportWriter;
import net.excel.report.base.Parameter;
import net.excel.report.base.element.ElementFactory;
import net.excel.report.base.element.FieldVariable;
import net.excel.report.base.element.ParameterVariable;
import net.excel.report.base.element.Variable;
import net.excel.report.config.DataSourceConfig;
import net.excel.report.config.ReportConfig;
import net.excel.report.config.ReportConfig.SheetConfig;
import net.excel.report.datasource.BaseDataSource;
import net.excel.report.datasource.IDataSource;
import jxl.Cell;
import jxl.CellType;
import jxl.CellView;
import jxl.Range;
import jxl.Workbook;
import jxl.format.CellFormat;
import jxl.write.Label;
import jxl.write.WritableCell;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
/**
* 报表生成核心类,该类负责每个具体报表的初始化(如从配置管理对象reportManager中取得具体报表对应的
* 配置信息,并根据报表的配置信息生成相应风格报表的生成器对象(如CardStyleReport),
* 在完成对生器对象的出世化后调用后者去分析模板文件并生成相应的报表数据。<br>
* 注:每一个报表输出请求都会对应一个报表(report)对象实例,
* @author juny
*/
public class Report {
private static Logger log = Logger.getLogger(Report.class);
/**
* 构造一个报表对象,并传入对象实例的构建者(报表引擎对象),因为一些配置参数信息和配置对象都只有在报表引擎对象中可见。
* @param rm 报表引擎对象实例
*/
public Report(ReportEngine rm){
this.reportEngine = rm;
}
/**
* 初始化报表,初始化配置文件,报表数据源等信息。
* @param config 当前需打印报表的配置信息对象
* @param params 参数map
* @throws Exception
*/
public void initializeReport(ReportConfig config, Map params)
throws Exception{
this.reportConfig = config;
this.params = params;
//取得数据源
if(log.isDebugEnable()){
log.debug("Getting data source.....");
}
this.dataSources = getAllDataSource(reportConfig, params);
if(null == this.dataSources){
throw new Exception(" Error: System couldn't get any datasource!");
}
//初始化所有数据源的初始化参数配置信息<param-init name="arg1" value="$F{ds.field}"/>
initAllDataSourceParams(params);
//运行用户嵌入的对象
invokeEmbeddedObjects(reportConfig, this.dataSources, params);
}
/**
* 释放报表生成过程中用到的一些资源
*/
public void release(){
if(null != this.dataSources){
try{
Collection values = this.dataSources.values();
Iterator itr = values.iterator();
while(itr.hasNext()){
((IDataSource)itr.next()).destroy();
}
}catch(Exception e){
log.error("While release report." + e.getMessage());
}
}
}
/**
* 根据传入参数,取得所有报表数据源对象实例,并初始化好数据源.
* @param report 当前需打印报表的配置信息对象
* @param params 参数map
* @return 返回初始化好的数据源实例map
* @throws Exception
*/
private Map getAllDataSource(ReportConfig report, Map params)
throws Exception {
Map dataSource = new HashMap();
SheetConfig sheet = null;
DataSourceConfig dsConfig = null;
BaseDataSource ds = null;
String[] sheets = report.getSheetName();
Object[] dsNames = null;
for(int i=0; i<sheets.length; i++){
sheet = report.getSheet(sheets[i]);
dsNames = sheet.getDataSourceNames();
for(int j=0; j<dsNames.length; j++){
String dsName = (String)dsNames[j];
dsConfig = sheet.getDataSource(dsName);
ds = (BaseDataSource)reportEngine.getDataSourceInstance(dsConfig, dsName);
//取得该数据源实例在配置文件中配置的初始化参数
ds.setParamInit(sheet.getDataSourceParamInit(dsName));
if(getParamsValue(ds, params)){
//初始化数据源时暂时不检索数据。
//ds.queryData();
}
dataSource.put((String)dsNames[j], ds);
}
}
return dataSource;
}
/**
* 初始化所有输入数据源的输入参数
* @param params 请求打印报表的输入参数map
*/
private void initAllDataSourceParams(Map params){
Iterator itr = this.dataSources.entrySet().iterator();
Entry entry = null;
BaseDataSource ds = null;
while(itr.hasNext()){
entry = (Entry)itr.next();
ds = (BaseDataSource)entry.getValue();
initDataSourceParam(ds, params);
}
}
/**
* 初始化输入数据源的输入参数。该函数会根据数据源配置的param-init节点的参数配置信息,
* 生成相应的变量对象,如(配置一个$F{dsName.field1})会生成一个对应dsName.fields的变量对象实例),
* 配置一个$P{param1}则又会生成一个对应param1的参数变量对象实例。如果两者都不是则系统会生成一个
* 常量对象实例。
* @param ds 数据源对象实例
* @param params 请求打印报表的输入参数map
*/
private void initDataSourceParam(BaseDataSource ds, Map params){
Map paramInit = ds.getParamInit();
List dsParams = null;
Variable var = null;
String varTemplet = null;
if(null != paramInit){
dsParams = ds.getConfig().getParams();
List paramTypes = ds.getConfig().getParamTypes();
if(null != dsParams){
if(dsParams.size() != paramInit.size()){
log.warn("The initialial parameters are not equal the datasource config parameters!");
}
for(int i=0; i<dsParams.size(); i++){
if(log.isDebugEnable()){
log.debug("param-init name=" + dsParams.get(i) +
" value=" + paramInit.get(dsParams.get(i))+
" type=" + paramTypes.get(i));
}
var = ElementFactory.getVariableInstances(
paramInit.get(
(String)dsParams.get(i)
).toString()
);
if(null != var){
//设置变量的数据类型
var.setValueType((String)paramTypes.get(i));
//配置相应变量对象的初始化参数。
if(var.getType() == Variable.VARIABLE_TYPE_FIELD){
((FieldVariable)var).setDataSource(this.dataSources);
}else if(var.getType() == Variable.VARIABLE_TYPE_PARAMETER){
((ParameterVariable)var).setParam(params);
}
//将配置好的变量对象替换原来的变量定义字符串
paramInit.put((String)dsParams.get(i), var);
}
}
}
}
}
/*
* 根据传入的datasource名称,取得数据源源实例,
* 如果数据源配置了参数则取得参数值并重新检索数据源。
*/
private IDataSource getDataSource(String dsName)throws Exception {
Object variable = null, tempObj = null;
boolean resetParam = false;
BaseDataSource ds = (BaseDataSource)this.dataSources.get(dsName);
if(null != ds){
String temp = "", value = "";
Map paramsInit = ds.getParamInit();
List params = ds.getConfig().getParams();
if(null != paramsInit && null != params){
if(paramsInit.size() != params.size()){
log.warn("The initialial parameters are not equal the datasource config parameters! 2");
}
//取得检索组数据的DataSource的参数值
for(int i=0; i<params.size(); i++){
variable = paramsInit.get((String)params.get(i));
if(null != variable){
String fieldValue = null;
if(variable instanceof Variable){
tempObj = ((Variable)variable).getValue();
if(null != tempObj){
fieldValue = tempObj.toString();
}
}else{
fieldValue = getDataFromDataSource(dataSources, "[" + variable + "]");
}
if(null != fieldValue){
ds.setParameter((String)params.get(i), fieldValue);
resetParam = true;
}
}
}
//如果更改过数据源参数,则需从新检索数据.
if(resetParam){
ds.queryData();
}
}
}else{
log.error("Fail to get datasource " + dsName);
}
return ds;
}
/**
* 查询报表是否存在嵌入对象,如果存在则生成该对象并调用该对象处理函数。
* @param reportConfig 当前打印报表对应的配置对象实例
* @param dataSources 当前打印报表对应的所有数据源
* @param params 打印报表请求输入的参数map
* @throws Exception
*/
private void invokeEmbeddedObjects(ReportConfig reportConfig,
Map dataSources,
Map params) throws Exception {
String objectName = reportConfig.getEmbeddedObject();
if(null == objectName || "".equals(objectName)){
return;
}
try{
if(log.isDebugEnable()){
log.debug("Load embedded object for class " + objectName);
}
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
if (classLoader == null) {
classLoader = ReportEngine.class.getClassLoader();
}
Object obj = classLoader.loadClass(objectName).newInstance();
if(obj instanceof IReportEntry){
IReportEntry reportEntry = (IReportEntry)obj;
reportEntry.execute(reportConfig, dataSources, params);
}else{
log.error("Embedded objects must be instance of IReportEntry");
}
}catch(Exception e){
log.error("Catched an Exception when process user embedded object " + objectName);
throw e;
}
}
/**
* 按照当前excel sheet模板定义的格式生成相应的excel报表。<br>
* 该函数首先根据sheet配置对象生成对应报表生成对象实例。<br>
* 在调用后者来生成具体的报表。
* @param sheet 用户定义的模板sheet对象
* @param sheetConfig 当前模板sheet对应的配置对象。
* @throws Exception
*/
private void writeSheetEx(WritableSheet sheet,
SheetConfig sheetConfig
) throws Exception{
//根据报表的配置文件取得数据读写对象
IReportWriter writer = WriterFactory.getWriterFactory()
.getReportWriter(sheetConfig);
if(null == writer){
throw new Exception("Error: System couldn't get report writer! " +
"Please confirm you have defined a correct report style!");
}
writer.setReportConfig(sheetConfig);
writer.setDataSources(this.dataSources);
writer.setParameters(this.params);
writer.analysisTemplet(sheet);
Parameter param = new Parameter();
param.dataSources = this.dataSources;
param.sheet = sheet;
param.params = this.params;
writer.writeData(param);
}
/*
* 取得参数值
*/
private boolean getParamsValue(IDataSource ds, Map params){
String key = null, value = null;
boolean bRet = true;
DataSourceConfig dsConfig = ds.getConfig();
String dsName = ds.getName();
List cfgParams = dsConfig.getParams();
for (int i = 0; i < cfgParams.size(); i++) {
key = dsName + "." + cfgParams.get(i);
value = (String) params.get(key);
if (null == value || "".equals(value)) {
log.warn("Warning: Fail to get the parameter's value. " +
"datasource name=" + dsName +
"parameter name=" + cfgParams.get(i));
bRet = false; //没有配制完所有的参数。
} else {
ds.setParameter((String) cfgParams.get(i), value);
}
}
return bRet;
}
/*
* 将报表数据写到传入的输出流中。
*/
public void writeData(OutputStream os) throws Exception {
WritableWorkbook wb = null;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -