将表中的数据导到Excel中步骤公用抽象
将表中的数据导到Excel中方法公用抽象
一、现在业务需求如下:
因为需要导出做业务分析,所以要将许多表中的数据导出来,但是这些导出数据的功能都是单独分开的。即:每个按钮导出一张表数据,现在有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中就可以了。