一、现在业务需求如下:
因为需要导出做业务分析,所以要将许多表中的数据导出来,但是这些导出数据的功能都是单独分开的。即:每个按钮导出一张表数据,现在有60多个按钮,也就是要到处60多张表数据。我们不能每次都单独写方法去导出数据,所以必须想办法写公共方法。
二、分析:
1.需要动态的改变Excel的title
2.表结构不一样怎么才能和各自的Excel对应起来了?
三、结论:
我们将Excel表结构和数据库中的表结构设置成一个映射关系,可以将这种映射关系放在表里面体现,也可以制作成xml体现这种关系。在本篇博客中我们使用第二种——xml体现。
四、使用的技术:SSH,DOM4j,POI
四、代码与逻辑
1.首先将xml准备好
<?xml version="1.0" encoding="UTF-8"?> <tables> <table tableName="testTable1" tableCName="测试表1"> <column columnName="column1" columnCName = "列名1"></column> <column columnName="column2" columnCName = "列名2"></column> <column columnName="column3" columnCName = "列名3"></column> <column columnName="column4" columnCName = "列名4"></column> </table> <table tableName="testTable2" tableCName="测试表2"> <column columnName="column1" columnCName = "列名1"></column> <column columnName="column2" columnCName = "列名2"></column> <column columnName="column3" columnCName = "列名3"></column> <column columnName="column4" columnCName = "列名4"></column> </table> <table tableName="pd_lmrisk" tableCName="险种表"> <column columnName="riskCode" columnCName = "险种代码"></column> <column columnName="riskName" columnCName = "险种名称"></column> <column columnName="riskVer" columnCName = "险种版本"></column> <column columnName="edorFlag" columnCName = "是否能做保全"></column> </table> </tables>
配置文件说明:这个配置文件中配置了多张表结构。我们以表名叫做:pd_lmrisk的节点为例。这个表中有四个字段:riskCode,riskName,riskVer,edorFlag(这些字段是区分大小写的,其实这些事项目中的实体类的属性)。对应到Excel的表头(title)就是险种代码,险种名称,险种版本,是否能做保全。也就是说,导出Excel表格含有四列。
2.编辑导出页面:
<form action="${ctx}/test/downloadRisk.do" method="post"> 请输入下载的表名:<input name="tableName" type="text" /> <input type="submit"/> </form>
就是一个简单的form表单提交
3.struts配置文件:
<action name="downloadRisk" class = "pdlmRiskAction" method = "downloadRisk"> <result name="success" type="stream"> <!-- 指定下载文件的内容类型,text/plain是默认类型 --> <param name="contentType">application/msexcel</param> <!-- inputName默认值是inputStream,如果action中用于读取下载文件内容的属性名是inputStream,那么可以省略这个参数 --> <!--动态获取文件名,从Action中的取得filename--> <param name="contentDisposition">attachment;filename=${fileName}</param> <param name="bufferSize">4096</param> </result> </action>
struts提供了非常简单的文件下载方案
4.Action层的方法
public void downloadRisk() throws Exception{ fileName= new String("导出险种数据.xls".getBytes("gb2312"), "ISO8859-1" ); this.getResponse().setHeader("content-disposition", "attachment;filename="+fileName); this.getResponse().setContentType("application/msexcel"); pdlmRiskService.downloadRisk(tableName,this.getResponse().getOutputStream()); }
5.Service层的方法
@Override public void downloadRisk(String tableName,OutputStream responseOutputStream) { String path = System.getProperty("user.dir"); try { List<PDLMRisk> list = this.find(QueryRule.getInstance()); //需要导出的数据 //调用核心方法,返回Excel HSSFWorkbook excel = XMLUtil.createExcel(path+"\\TablesConfig.xml", tableName,list); excel.write(responseOutputStream); } catch (Exception e) { e.printStackTrace(); } }
6.核心方法:
package ins.common.util; import java.io.File; import java.math.BigDecimal; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFCellStyle; import org.apache.poi.hssf.usermodel.HSSFFont; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.Font; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader; /** * * @title XMLUtil * @description 操作xml的方法很多,DOM4j性能最好。Sun的JAXM和Hibernate都是用的DOM4J * @author hadoop * @version * */ public class XMLUtil { public static Map<String,String> readXML(String XMLPath,String tableName) throws Exception{ //读取文件 SAXReader saxReader = new SAXReader(); Document doc = saxReader.read(new File(XMLPath)); //得到根节点 Element rootElement = doc.getRootElement(); //得到所有的table节点 Iterator<Element> tableIt = rootElement.elementIterator("table"); //返回的别名和表头Map<列名,表头> Map<String,String> N2C = new HashMap<String, String>(); //开始处理xml while(tableIt.hasNext()){ //得到table节点 Element elements = tableIt.next(); System.out.println(elements.attributeValue("tableName")); //如果table节点的tablename和传递进来的tablename一致,那么收集列和表头 if(tableName.equals(elements.attributeValue("tableName"))){ //得到所有的列 List<Element> columns = elements.elements("column"); for(int i = 0 ; i < columns.size() ; i++){ Element temp = columns.get(i); String key = temp.attributeValue("columnName"); String value = temp.attributeValue("columnCName"); N2C.put(key, value); } break; } } return N2C; } // public static void main(String[] args) throws Exception { // XMLUtil test = new XMLUtil(); // String path = System.getProperty("user.dir"); // Map<String,String> N2C = test.readXML(path+"\\TablesConfig.xml", "testTable1"); // for (String key : N2C.keySet()) { // System.err.println(N2C.get(key)); // } // // } public static HSSFWorkbook createExcel(String path, String tableName,List<?> list) { try { //用来存储数据的list List<Map<String, Object>> excelList = new ArrayList<Map<String, Object>>(); Map<String,String> N2C = readXML(path, tableName); //把bean封装成map for(int i=0;i<list.size();i++){ Map<String,Object> map = new HashMap<String,Object>(); map = ExcelToMap.convertBean(list.get(i)); excelList.add(map); } //新建一个excel HSSFWorkbook wbs = new HSSFWorkbook(); // 得到一个工作区 HSSFSheet childSheet = wbs.createSheet(); // 得到标题行 HSSFRow rowTitle = childSheet.createRow(0); //设置行的样式 HSSFCellStyle headStyle=wbs.createCellStyle(); HSSFFont font=wbs.createFont(); //红色字体 font.setColor(Font.COLOR_RED); headStyle.setFont(font); //在excel中写入标题 int i = 0; for(String key : N2C.keySet()){ HSSFCell cell=rowTitle.createCell(i++); cell.setCellStyle(headStyle); cell.setCellValue(N2C.get(key)); } //在excel中写入数据 for(int k=0;k<excelList.size();k++){ //从第二行开始 HSSFRow row=childSheet.createRow(k+1); i = 0; for(String key : N2C.keySet()){ HSSFCell rowCell=row.createCell(i++); Object value=excelList.get(k).get(key); if(null!=value){ if(value instanceof BigDecimal){ //数值类型 BigDecimal big=(BigDecimal)value; rowCell.setCellValue(big.doubleValue()); }else{ rowCell.setCellValue(value.toString()); } }else{ rowCell.setCellValue(""); } } } return wbs; } catch (Exception e) { e.printStackTrace(); } return null; } }
核心方法主要有两个:
1.读取xml得到表和Excel的映射关系
2.写入数据,将查询到的list数据插入到Excel中
终结:
有了上面的方法,我们如果还想导出什么表的数据,只需将对应的映射关系添加到xml中就可以了。
相关推荐
VBA(Visual Basic for Applications)是Microsoft Office套件中用于自动化和自定义工作流程的一种编程...无论你是数据分析员、财务人员还是任何需要处理大量数据的工作者,这本书都将助你在Excel的世界里游刃有余。
7.9.2 DataTable 数据表对象 7.9.3 DataRow 数据行对象 7.9.4 DataView 数据视图对象 7.10 DataReader 数据访问对象 7.10.1 DataReader 对象概述 7.10.2 DataReader 读取数据库 7.10.3 异常处理 7.11 连接池概述 ...
- **D选项**:“abstract void method()”——抽象方法必须在子类中实现,也不能直接通过类名调用。 ### 7. DriverManager 类的作用 **知识点概述:** DriverManager 类是Java中用于管理数据库驱动和建立数据库...
这是整部学习资料 由于太大第一章免费供应给大家 在我的上传资源中 如果觉得还不过希望大家给个好评 当然具体本书的作者就不深究了把! 第1章 认识ASP.NET 3.5 1.1 什么是ASP.NET 1.1.1 .NET历史与展望 1.1.2 ASP...
3.9.3 虚方法的抽象类 3.9.4 抽象属性 3.10 委托和事件 3.10.1 委托 3.10.2 声明事件 3.10.3 引发事件 3.10.4 订阅事件 3.10.5 委托和事件 3.11 类命名 3.11.1 命名空间的命名 3.11.2 类的命名原则 3.11.3 接口的...
3.9.3 虚方法的抽象类 3.9.4 抽象属性 3.10 委托和事件 3.10.1 委托 3.10.2 声明事件 3.10.3 引发事件 3.10.4 订阅事件 3.10.5 委托和事件 3.11 类命名 3.11.1 命名空间的命名 3.11.2 类的命名原则 3.11.3 接口的...
3.9.3 虚方法的抽象类 3.9.4 抽象属性 3.10 委托和事件 3.10.1 委托 3.10.2 声明事件 3.10.3 引发事件 3.10.4 订阅事件 3.10.5 委托和事件 3.11 类命名 3.11.1 命名空间的命名 3.11.2 类的命名原则 3.11.3 接口的...
3.9.3 虚方法的抽象类 3.9.4 抽象属性 3.10 委托和事件 3.10.1 委托 3.10.2 声明事件 3.10.3 引发事件 3.10.4 订阅事件 3.10.5 委托和事件 3.11 类命名 3.11.1 命名空间的命名 3.11.2 类的命名原则 3.11.3 接口的...
- **抽象数据模型**:支持抽象的数据模型,如关系模型。 ### 18. Windows快捷键 - **Ctrl+V**:复制粘贴操作的快捷键。 ### 19. 继承的概念 - **错误理解**:基类并不会自动继承派生类的属性,相反,派生类会...
3. 函数在编程中是一种功能抽象,可以降低代码复杂性并提高可维护性。但使用函数的目的不只是为了增加代码复用,它还可以提高代码的可读性和模块化。错误答案是B。 4. 随机存储器(RAM)分为DRAM(动态随机存取...
这一概念起源于上世纪60年代约翰·麦卡锡提出的公用计算服务理念,随着分布式计算、高性能存储、虚拟化等技术的发展,以及数据量的增长和对计算效率的需求,云计算逐渐形成并发展。 云计算的产生和发展历程中,...
实例125 将数据保存到指定的文件中 175 实例126 将由键盘中录入的信息保存到文件中 176 实例127 一个文件变成多个小文件 178 实例128 多个小文件合成一个文件 181 实例129 统计指定文件中的字符个数 ...
实例125 将数据保存到指定的文件中 175 实例126 将由键盘中录入的信息保存到文件中 176 实例127 一个文件变成多个小文件 178 实例128 多个小文件合成一个文件 181 实例129 统计指定文件中的字符个数 183 实例130 ...
这是用框架烧瓶制作的python脚本 :growing_heart: ,它对从用户接收的表单输入执行操作,并将其存储在CSV文件(逗号分隔文件)中,并且还读取和检索数据以将其显示在html文件中。 所有这些东西使它成为实时数据库的...
实例125 将数据保存到指定的文件中 175 实例126 将由键盘中录入的信息保存到文件中 176 实例127 一个文件变成多个小文件 178 实例128 多个小文件合成一个文件 181 实例129 统计指定文件中的字符个...
实例125 将数据保存到指定的文件中 175 实例126 将由键盘中录入的信息保存到文件中 176 实例127 一个文件变成多个小文件 178 实例128 多个小文件合成一个文件 181 实例129 统计指定文件中的字符个数 183 实例130 ...
实例125 将数据保存到指定的文件中 175 实例126 将由键盘中录入的信息保存到文件中 176 实例127 一个文件变成多个小文件 178 实例128 多个小文件合成一个文件 181 实例129 统计指定文件中的字符个数 183 实例...