润乾报表作为报表编辑工具使用起来十分的简单方便,只需要简单的属性设置便可以实现导出、打印等功能(具体参见润乾开发应用文档),令人很郁闷的是润乾的导出只是单表的导出。
最近就有这么一个需求:有很多.raq报表文件,在一个页面中列出所有的文件的名称,通过复选框选中下载,要求导出到一个excel中,分不同的sheet页展示(不知各位是否明白此需求,我的表达能力有限请见谅)。
郁闷了我好一阵子,问同事都没有这么做过!
闲着没事翻看润乾jar包,发现了一些端倪。在润乾安装目录里有润乾API,闲着没事可以翻阅。
API中有ExcelReport类可以帮助我们实现上面的需求。
话不多说看代码:
package cn.com.victorysoft.wellinfo.util; import java.io.FileOutputStream; import java.sql.Connection; import java.util.Map; import javax.sql.DataSource; import org.springframework.jdbc.core.JdbcTemplate; import com.runqian.base4.util.DBTypes; import com.runqian.report4.usermodel.Context; import com.runqian.report4.usermodel.DataSourceConfig; import com.runqian.report4.usermodel.Engine; import com.runqian.report4.usermodel.IReport; import com.runqian.report4.util.ReportUtils; import com.runqian.report4.view.excel.ExcelReport; /** * @Description 多个润乾报表导出到一个excel中的不同sheet页中 * @ClassName ExportReport2 * @author Gao Jie-quan * @Created 2010 Oct 12, 2010 3:23:35 PM */ public class ExportReport { /** * @Description 一些必须设置的属性 * @created 2010 Oct 12, 2010 4:32:39 PM */ /** * @Description 润乾.raq文件存储路径, * 此属性可以不设置,但是方法传值reportName时必须包含物理路径, * @field String reportPath * @created 2010 Oct 12, 2010 5:14:21 PM */ private String reportPath = ""; /** * @Description 导出的excel存储路径 * 此属性可以不设置,但是方法传值excelFileName的时候必须包含物理路径, * @field String excelPath * @created 2010 Oct 12, 2010 5:14:34 PM */ private String excelPath=""; /** * @Description excel文件名 * @field String excelFileName * @created 2010 Oct 12, 2010 5:14:47 PM */ private String excelFileName; /** * @Description 数据源 * @field DataSource dataSource * @created 2010 Oct 12, 2010 5:14:57 PM */ private DataSource dataSource; /** * @Description 润乾中使用的默认数据源名称 * @field String reportDataSource * @created 2010 Oct 12, 2010 5:15:08 PM */ private String reportDataSource; /** * @Description 构造数据源配置的相关属性,包含默认初始值 * @created 2010 Oct 12, 2010 4:32:39 PM */ /** * @Description 数据源类型,默认为Oracle 参见com.runqian.base4.util.DBTypes * @field int dbType * @created 2010 Oct 12, 2010 5:05:12 PM */ private int dbType = DBTypes.ORACLE; /** * @Description 是否需要转换检索内容的编码 *@field boolean needTranContent * @created 2010 Oct 12, 2010 5:09:48 PM */ private boolean needTranContent = true; /** * @Description 数据源使用的字符集名,默认为GBK * @field String dbCharset * @created 2010 Oct 12, 2010 5:11:18 PM */ private String dbCharset = "GBK"; /** * @Description 客户端使用的字符集名,默认为GBK * @field String clientCharset * @created 2010 Oct 12, 2010 5:11:40 PM */ private String clientCharset = "GBK"; /** * @Description 是否需要转换检索语句的编码 * @field boolean needConvert * @created 2010 Oct 12, 2010 5:12:50 PM */ private boolean needTranSentence = false; /** * @Description 保存excel * @param param 报表参数 * @param macro 报表宏 * @param reportName .raq名称(要包含.raq后缀), * 如果reportPath属性没有设置,那么reportName必须包含完整的物理路径 * @param sheetName 保存到excel中sheet页的名称, * @throws Exception * @ReturnType void * @author Gao Jie-quan * @Created 2010 Oct 12, 20103:23:46 PM */ public void saveExcel(Map param, Map macro, String[] reportName, String[] sheetName) throws Exception{ int flag = 0; ExcelReport erp=null; JdbcTemplate JT = new JdbcTemplate(); JT.setDataSource(this.dataSource); Connection con = JT.getDataSource().getConnection(); DataSourceConfig dsoc = new DataSourceConfig(this.dbType, this.needTranContent, this.dbCharset, this.clientCharset, this.needTranSentence); //判断excelFileName是不是为“”或null,以及是不是excel类型 if(!"".equals(this.null2blank(this.excelFileName)) && this.isExcelFile(this.excelFileName)){ FileOutputStream fos = new FileOutputStream((this.null2blank(this.excelPath)+this.excelFileName).trim()); try { erp = new ExcelReport(); } catch (Throwable e) { e.printStackTrace(); } if(reportName != null && reportName.length>0){ //初始化数组 IReport[] rd = new IReport[reportName.length]; Context[] context = new Context[reportName.length]; Engine engine[] = new Engine[reportName.length]; IReport iReport[] = new IReport[reportName.length]; //如果sheetName为空或者长度为零,那么设置默认选项 if (sheetName == null || sheetName.length<=0) { sheetName = new String[reportName.length]; for (int i = 0; i < reportName.length; i++) { sheetName[i] = "report_"+String.valueOf(i); } } for (int i = 0; i < reportName.length; i++) { if(!"".equals(this.null2blank(reportName[i]))){ //读取报表模板,把*.raq文件读入内存,并实例化ReportDefine rd[i] = ReportUtils.read((this.null2blank(this.reportPath)+reportName[i]).trim()); //新建上下文对象,在上下文对象中设置数据源 context[i] = new Context(); context[i].setDefDataSourceName(this.reportDataSource); context[i].setConnection(this.reportDataSource,con); context[i].setDataSourceConfig(this.reportDataSource, dsoc); //设置参数和宏 if(param != null && param.size()>0){ context[i].setParamMap(param); } if(macro != null && macro.size()>0){ Object[] array = macro.keySet().toArray(); for (int j = 0; j < array.length; j++) { context[i].setMacroValue(array[j].toString(), macro.get(array[j]).toString()); } } //运算报表,并在页面上输出报表 engine[i] = new Engine(rd[i],context[i]); iReport[i] = engine[i].calc(); //构建每个sheet页 erp.addPage(iReport[i],sheetName[i]); flag ++; } } }else { throw new Exception("reportName为“”或null"); } //导出Excel if (flag != 0) { erp.out(fos); } fos.flush(); fos.close(); }else { throw new Exception("excelFileName为“”或null或不是excel类型"); } } /** * 判断字符串是否为null,如果为null,则转换为“”,否则返回源字符串 * * @param variable * @return */ private String null2blank(String variable) { if (variable == null) variable = ""; return variable; } /** * @Description 判断是不是excel文件类型 * @param excelName * @return * @ReturnType boolean * @author Gao Jie-quan * @Created 2010 Oct 13, 20108:58:24 AM */ private boolean isExcelFile(String excelName){ boolean is = false; if(excelName.endsWith(".xls") || excelName.endsWith(".xlsx")){ is = true; } return is; } /** * @Description 相关属性的Get/Set方法 * @ReturnType String * @author Gao Jie-quan * @Created 2010 Oct 12, 20104:39:39 PM */ public String getReportPath() { return reportPath; } public void setReportPath(String reportPath) { this.reportPath = reportPath; } public String getExcelPath() { return excelPath; } public void setExcelPath(String excelPath) { this.excelPath = excelPath; } public String getExcelFileName() { return excelFileName; } public void setExcelFileName(String excelFileName) { this.excelFileName = excelFileName; } public DataSource getDataSource() { return dataSource; } public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; } public String getReportDataSource() { return reportDataSource; } public void setReportDataSource(String reportDataSource) { this.reportDataSource = reportDataSource; } public int getDbType() { return dbType; } public void setDbType(int dbType) { this.dbType = dbType; } public boolean isNeedTranContent() { return needTranContent; } public void setNeedTranContent(boolean needTranContent) { this.needTranContent = needTranContent; } public String getDbCharset() { return dbCharset; } public void setDbCharset(String dbCharset) { this.dbCharset = dbCharset; } public String getClientCharset() { return clientCharset; } public void setClientCharset(String clientCharset) { this.clientCharset = clientCharset; } public boolean isNeedTranSentence() { return needTranSentence; } public void setNeedTranSentence(boolean needTranSentence) { this.needTranSentence = needTranSentence; } }
以上是关键代码,完整代码示例请参见附加。代码排版有些乱,请童鞋们见谅,如果上面的代码不想看,就下载附件吧,附加注释很详细