excel导出(POI实现)

将数据excel导出是一种常见的功能,导出实现有两种方式,①用POI自身API创建Row和Cell,这种方式导出样式比较简单 ②通过读取模板的方式,将需要导出的项目如name写在Cell中,通过java反射机制获取属性name的值。示例模板文件如下:


上图中由于数据量不是固定的,所以要将第三行进行拷贝,然后遍历整个sheet,将数据填充。

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import com.biz.vo.bbcx.gbxx.TestDto;
import com.frame.util.Utils;
import sun.misc.Unsafe;

public class ExcelTool {

	public static int START_ROW =1;//被复制的开始行
	
	/**
	 * 导出EXCEL
	 * @param request
	 * @param response
	 * @param list 待导出的数据
	 * @throws Exception
	 */
	public static void exportExcel(HttpServletRequest request, HttpServletResponse response,List list)
			throws Exception {
		
		String templateFile =  "template.xls";//模板文件名
		String outputFile = "test.xls";//导出文件名

		outputFile = URLEncoder.encode(outputFile, "UTF-8");
		response.setContentType("application/msexcel; charset=utf-8");
		response.setHeader("Content-disposition", "attachment; filename=" + outputFile);// 设定输出文件头

        InputStream is = null;// 输入流对象  
		try {  
			   
			    //模板文件位于: WebContent/template/template.xls
			    String realpath = File.separator + "template" + File.separator  + templateFile;
	            is = request.getSession().getServletContext().getResourceAsStream(realpath);// 获取文件输入流  
	            HSSFWorkbook workbook2003 = new HSSFWorkbook(is);// 创建Excel2003文件对象  
	            HSSFSheet sheet = workbook2003.getSheetAt(0);// 取出第一个工作表,索引是0 
	            
	            //list数据,dto类型为TestDto
	            setListInfo(sheet, TestDto.class, list);
				OutputStream bos = response.getOutputStream();
				//将excel流对象写入response输出流中
				workbook2003.write(bos);
	            response.flushBuffer();
                bos.flush();
                bos.close();

	        } catch (Exception e) {  
	            e.printStackTrace();  
	        } finally {
	        	// 关闭文件流  
	            if (is != null) {  
	                try {  
	                    is.close();  
	               } catch (IOException e) {  
	                    e.printStackTrace();  
	               }  
	            } 
	        }  
	}
	
	/**
	 * 将classType型dataList数据写入excel的sheet中
	 * @param sheet
	 * @param classType
	 * @param dataList
	 */
	@SuppressWarnings("rawtypes")
	public static void setListInfo(HSSFSheet sheet, Class classType,
			List dataList) {
		int END_ROW = START_ROW + dataList.size();
		List mapList;
		try {
			mapList = reflectForgetData(classType, dataList);
		} catch (IOException e) {
			mapList = new ArrayList();
			e.printStackTrace();
		}
		if (mapList == null || mapList.size() == 0) {
			HSSFRow modRow = sheet.getRow(START_ROW + 1);
			sheet.removeRow(modRow);
		}
		// 获取模板行对象
		HSSFRow modRow = sheet.getRow(START_ROW + 1);
		for (int j = 1; j < mapList.size(); j++) {
			// 为各数据对象单位添加行
			sheet.shiftRows(START_ROW + j + 1, END_ROW, 1, true, false);
			HSSFRow newXSSFRow = sheet.createRow(START_ROW + j + 1);
			// 把模板里各行的内容复制到新生成的行里
			for (int k = 0; k < modRow.getLastCellNum(); k++) {
				HSSFCell modcell = modRow.getCell(k);
				HSSFCell newcell = newXSSFRow.createCell(k);
				if (null == modcell) {
					continue;
				}
				// 把模板里的cell相关属性设入新增cell
				newcell.setCellStyle(modcell.getCellStyle());
				newcell.setCellType(modcell.getCellType());
				if (null != modcell.getStringCellValue()
						&& !"".equals(modcell.getStringCellValue().trim())) {
					newcell.setCellValue(Utils.nvl(modcell.getStringCellValue()));
				}
			}
		}

		int cellIndex = START_ROW + 1;
		Map<String, Object> map = null;
		for (int mc = 0; mc < mapList.size(); mc++) {
			map = (HashMap) mapList.get(mc);
			// 输出行数
			int outputRowCnt = 0;
			// 开始循环遍历行,表头不处理,从数据对象单位开始行开始处理
			HSSFRow row = sheet.getRow(cellIndex);// 获取行对象
			if (row == null) {// 如果为空,不处理
				continue;
			}
			// 循环遍历单元格
			for (int j = 0; j < row.getLastCellNum(); j++) {
				HSSFCell cell = row.getCell(j);// 获取单元格对象
				if (cell == null) {// 单元格为空设置cellStr为空串
					continue;
				}
				if (map.containsKey(cell.getStringCellValue())) {
					if (map.get(cell.getStringCellValue()) != null) {
						cell.setCellValue(String.valueOf(map.get(cell
								.getStringCellValue())));
					} else {
						cell.setCellValue("");
					}
				}
			}
			cellIndex++;
			outputRowCnt++;
		}

	}
	/**
	 * 将传入数据映射到MAP中
	 * 
	 * @param classType
	 *            传入数据类型
	 * @param dataObj
	 *            传入数据
	 * @return 布尔值 是否复制成功
	 * @throws IOException
	 */
	public static List reflectForgetData(Class<?> classType, List<Object> dataObjs)
			throws IOException {
		// 输出结果
		List resultList = new ArrayList();
		try{
			// 将所有OBJ内的数据放入map
			//创建此类型的空对象  
			Field fu = Unsafe.class.getDeclaredField("theUnsafe");  
			fu.setAccessible(true);  
			Unsafe us = (Unsafe) fu.get(null);  
			Object newObj = us.allocateInstance(classType);
			
			//获取所有成员(包括private)的值,并拷贝到新对象中  
			Field[] fields = classType.getDeclaredFields();  
			for(int i = 0;i < dataObjs.size();i++)
			{
				// 取得单个元素
				Object dataObj = dataObjs.get(i);
				// 单个对象
				Map<String, Object> map = new HashMap();
				for (Field f : fields) {
					//不拷贝static成员和final成员  
					if (Modifier.isStatic(f.getModifiers()) || Modifier.isFinal(f.getModifiers())) {  
						continue;  
					}
					f.setAccessible(true);  
					//Object fieldValue = f.get(dataObj);  
					//f.set(newObj, fieldValue);
					map.put(f.getName(), f.get(dataObj));
				}
				resultList.add(map);
			}
		}catch(Exception e){
			e.printStackTrace();
		}
		return resultList;
	}
	
}

其中TestDto对象应包含模板中提到的blackboxNo,materialType等字段。

请求中调用:

//导出
		List<TestDto> listdata = testervice.queryList();
		ExcelTool.exportExcel(request, response, gbList);

最终得到的效果如下:


注:用到的jar包有:

poi-ooxml-schemas-3.7.jar

poi-ooxml-3.7.jar

poi-3.9-20121203.jar


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值