package common; import me.alad.common.AladdinLogger; 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.HSSFWorkbook; import org.apache.poi.ss.usermodel.*; import javax.servlet.http.HttpServletResponse; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.*; import java.lang.reflect.Field; import java.util.*; /** * Created with IntelliJ IDEA. * User: user * Date: 14-7-18 * Time: 上午9:33 * To change this template use File | Settings | File Templates. */ /** * 处理实体生成excel工具类 * 使用规范 * 1.如果headMap,不指定行高,列宽都默认值,实体每个属性都输出 * 2,如果指定了列的排序比如("name$sort",0),那么headMap中的其他实体的属性需要全部自定排序,并且不能序号重复,不然可能造成空列的情况 * */ public class ExcelUtil { private static final AladdinLogger log = AladdinLogger.getLogger(ExcelUtil.class); /** * 转换集合成excel文件 * * @param fileName 转换成excel的文件名 * @param list 需要转换的类的集合 * @param headMap 表头map,表头字段map,key对应list的实体的属性,value对应excel中显示的列名,传入为null 表示实体属性全部输出 * headMap.put("excel_column$Width",20); //默认列宽 * headMap.put("excel_row$Height",20*20); 默认行高 * 显示:headMap.put("name","名字")excel中显示名字这列 * 排序:headMap.put("name$Sort",0); 0 排第一列 如果不指定,按照属性默认排序 * 某列的宽度 headMap.put("name$Width",20*256); 默认20字符 * */ public static void exportExcelFromList(String fileName, List list, Map headMap,HttpServletResponse response) { try { //数据为空提示 if (list == null || list.size() == 0) { response.setHeader("Content-type", "text/html;charset=UTF-8"); response.setCharacterEncoding("UTF-8"); OutputStream os = response.getOutputStream(); OutputStreamWriter writer = new OutputStreamWriter(os,"utf-8"); writer.write("<script>"); writer.write("alert('数据为空,生成excel失败!');window.history.go(-1);"); writer.write("</script>"); writer.flush(); writer.close(); os.close(); return ; } HSSFWorkbook hwb = new HSSFWorkbook(); int countRow = list.size();//总行数 int countSheet = 1;//总工作表 int sheetCountRow = countRow;//每个工作表显示的行数 int sheetMaxCount=65000; //每个工作表最大行数 if (countRow > sheetMaxCount) { countSheet = countRow % sheetMaxCount == 0 ? countRow / sheetMaxCount : countRow / sheetMaxCount + 1; sheetCountRow = sheetMaxCount; } if (countSheet > 256) { return; } CellStyle headStyle = setHeaderCellStyle(hwb); CellStyle style = setRowCellStyle( hwb);//设置默认样式 for (int i = 0; i < countSheet; i++) { Sheet sheet = hwb.createSheet("sheet" + (i + 1)); int defaultColumnWidth =20; if(headMap!=null){ defaultColumnWidth =headMap.get("excel_column$Width") == null ? defaultColumnWidth : Integer.valueOf(headMap.get("excel_column$Width").toString()); } sheet.setDefaultColumnWidth(defaultColumnWidth); Short defaultHeight =(short) (20*20); if(headMap!=null){ defaultHeight =headMap.get("excel_row$Height")==null?defaultHeight:Short.valueOf(headMap.get("excel_row$Height").toString()); } sheet.setDefaultRowHeight(defaultHeight); Row firstRow = sheet.createRow(0); // 下标为0的行开始 List<Field> fields =getDeclaredFields(list.get(0)); int countHead = 0; //表头 for (Field item : fields) { String name = item.getName(); // 属性名 Integer sort=countHead; Cell cell =null; if(headMap ==null || headMap.isEmpty()){ //遍历全部属性 cell = firstRow.createCell(sort); sheet.autoSizeColumn(sort); //自适应 cell.setCellStyle(headStyle); cell.setCellValue(name); countHead++; }else{ if(headMap.get(name) != null){ if (headMap.get(name+"$Sort") != null) { //改变列名 sort= Integer.valueOf(headMap.get(name+"$Sort").toString()); } if(headMap.get(name+"$Width")!=null ) { sheet.setColumnWidth(sort,Integer.valueOf(headMap.get(name+"$Width").toString())); }else{ //自适应 sheet.autoSizeColumn(sort); } cell = firstRow.createCell(sort); cell.setCellStyle(headStyle); cell.setCellValue(headMap.get(name).toString()); countHead++; } } } for (int j = 0; j < sheetCountRow; j++) { int index = i * sheetMaxCount + j;//list集合下表 if (index > countRow - 1) {//list已经全部循环取出来了,结束整个循环 break; } // 创建一行 Row row = sheet.createRow(j + 1); int count = 0; for (Field item : fields) { String name = item.getName(); // 属性名 item.setAccessible(true); Cell cell =null; int sort = count; if(headMap == null || headMap.isEmpty()){ cell =row.createCell(sort); cell.setCellStyle(style); setCellTypeValue(cell,item,list.get(index)); count++; }else{ if( headMap.get(name) != null){ sort =headMap.get(name+"$Sort")==null ?count : Integer.valueOf(headMap.get(name+"$Sort").toString()); //填充类中需要填充的字段的值 cell =row.createCell(sort); cell.setCellStyle(style); setCellTypeValue(cell,item,list.get(index)); count++; } } } } } list = null; //清空list释放内存 OutputStream os = response.getOutputStream(); // 这个是弹出下载对话框的关键代码 response.setHeader("Content-disposition", "attachment;filename=" + ((null == fileName) || ("".equals(fileName.trim()))? (new Date().getTime() + "") : new String(fileName.trim().getBytes("gb2312"),"ISO8859-1")) + ".xls"); // 将工作簿进行输出 hwb.write(os); os.flush(); // 关闭输出流 os.close(); } catch (Exception e) { log.error("导出excel出错:"+e.getMessage()); } } /** * 个单元格设置类型,值 * @param cell 单元格 * @param item 反射属性类 * @param entity 集合中的实体 */ public static void setCellTypeValue(Cell cell,Field item,Object entity) { //Boolean String typeName =item.getGenericType().toString(); try{ if(typeName.equals("class java.lang.Boolean") || typeName.equals("boolean")){ //后面是它的基本类型 cell.setCellType(HSSFCell.CELL_TYPE_BOOLEAN); if(item.get(entity)!=null){ cell.setCellValue((Boolean) item.get(entity)); } return; } // Double if(typeName.equals("class java.lang.Double") || typeName.equals("double")) { cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC); if(item.get(entity)!=null){ cell.setCellValue((Double)item.get(entity)); } return; } if( typeName.equals("class java.lang.Integer") || typeName.equals("int")){ cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC); if(item.get(entity)!=null){ cell.setCellValue((Integer)item.get(entity)); } return; } if(typeName.equals("class java.lang.Short") || typeName.equals("short")){ cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC); if(item.get(entity)!=null){ cell.setCellValue((Short)item.get(entity)); } return; } if(typeName.equals("class java.lang.Float") || typeName.equals("float")){ cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC); if(item.get(entity)!=null){ cell.setCellValue((Float)item.get(entity)); } return; } if(typeName.equals("class java.lang.Long") || typeName.equals("long")){ cell.setCellType(HSSFCell.CELL_TYPE_NUMERIC); if(item.get(entity)!=null){ cell.setCellValue((Long)item.get(entity)); } return; } //String 其他类型 cell.setCellType(HSSFCell.CELL_TYPE_STRING); if(item.get(entity)!=null){ cell.setCellValue((String) item.get(entity)); } }catch (Exception e){ log.error("类型转换出错"+e.getMessage()); } } /** * 获取属性集合,循环向上转型, 获取对象的属性,包括父类的 * @param object : 对象 * @return 属性的集合 */ public static List<Field> getDeclaredFields(Object object){ List<Field> fields = new ArrayList<Field>(); Class<?> clazz = object.getClass() ; for(; clazz != Object.class ; clazz = clazz.getSuperclass()) { try { fields.addAll(Arrays.asList(clazz.getDeclaredFields())); } catch (Exception e) { //这里甚么都不要做!并且这里的异常必须这样写,不能抛出去。 //如果这里的异常打印或者往外抛,则就不会执行clazz = clazz.getSuperclass(),最后就不会进入到父类中了 log.error("获取父类的属性出错"+e.getMessage()); } } return fields; } /** * 设置表头的单元格样式 * @param hwb * */ public static CellStyle setHeaderCellStyle(HSSFWorkbook hwb){ CellStyle style =hwb.createCellStyle(); Font font=hwb.createFont(); font.setFontHeightInPoints((short)12); font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); //字体增粗 //把字体应用到当前的样式 style.setFont(font); style.setAlignment(HSSFCellStyle.ALIGN_CENTER); style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); return style; } /** * 设置单元格样式 * @param hwb */ public static CellStyle setRowCellStyle(HSSFWorkbook hwb){ CellStyle style =hwb.createCellStyle(); style.setAlignment(HSSFCellStyle.ALIGN_CENTER); style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); return style; } // public static void main(String[] arg){ // CompanyOverValue overValue = new CompanyOverValue(); // overValue.setLicenseImages("xxxx"); // overValue.setRegistNumber("dfadfa"); // overValue.setPhone("1234566545"); // overValue.setAddress("你好啊。"); // List<CompanyOverValue> list = new ArrayList<CompanyOverValue>(); // list.add(overValue); // Map showHead = new HashMap(); // showHead.put("phone","电话"); // showHead.put("address","地址"); // showHead.put("registNumber","合同号"); // showHead.put("licenseImages","营业执照"); // // /* // 不指定排序就是默认类中属性的排序 // showHead.put("excel_head$Height",20); //表头一列的高度 // showHead.put("excel_row$Height",20); //指定excel每行高度 // showHead.put("phone$Sort",0); //指定列名排序 如果指定了其中一列其他的都要自己指定排序 // showHead.put("address$Sort",1); //指定列名排序 如果指定了其中一列其他的都要自己指定排序 // showHead.put("registNumber$Sort",2); //指定列名排序 如果指定了其中一列其他的都要自己指定排序 // showHead.put("licenseImages$Sort",3); //指定列名排序 如果指定了其中一列其他的都要自己指定排序 // showHead.put("licenseImages$Width",200); //置顶这列的宽度 // */ // HttpServletResponse response =null; //自己从controller中拿到 // ExcelUtil.exportExcelFromList("今天测试",list,showHead,response); // } }