将表中的数据导到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中就可以了。