package cn.timer.api.utils; import java.io.File; import java.io.IOException; import java.io.OutputStream; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.text.DecimalFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.lang3.reflect.FieldUtils; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFCellStyle; import org.apache.poi.hssf.usermodel.HSSFDataFormat; import org.apache.poi.hssf.usermodel.HSSFDateUtil; 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.poifs.filesystem.POIFSFileSystem; import org.apache.poi.ss.usermodel.BorderStyle; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.FillPatternType; import org.apache.poi.ss.usermodel.HorizontalAlignment; import org.apache.poi.ss.usermodel.VerticalAlignment; import org.springframework.web.multipart.MultipartFile; public class ExcelUtil<T> { /** * HSSFWorkbook excel 的文档对象 HSSFSheet excel 的表单 HSSFRow excel 的行 HSSFCell excel * 的格子单元 */ /** * 导出xls文件 * * @param title sheet标题 * @param headers 第一行标题 * @param dataset 集合数据/表单内容 * @param out * @param pattern */ public void exportExcel(String title, String[] headers, Collection<T> dataset, OutputStream out, String pattern) { // 创建工作簿 // SXSSFWorkbook workbook = new SXSSFWorkbook(1000); HSSFWorkbook workbook = new HSSFWorkbook(); // 创建SHEET页/表格页,title-表格标题 HSSFSheet sheet = (HSSFSheet) workbook.createSheet(title); // 设置表格默认列宽度为15个字节 sheet.setDefaultColumnWidth((short) 15); // 创建行,从0开始 HSSFRow row = (HSSFRow) sheet.createRow(0); // 创建单元格样式对象(设置样式) HSSFCellStyle ztStyle = workbook.createCellStyle(); // 创建字体对象 ztStyle.setAlignment(HorizontalAlignment.CENTER);// 水平居中 ztStyle.setVerticalAlignment(VerticalAlignment.CENTER);// 垂直居中 ztStyle.setFillForegroundColor((short) 42);// 前景填充色 // ztStyle.setFillForegroundColor(IndexedColors.YELLOW.index);//前景填充色-黄色 ztStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);// 设置前景填充样式 // 边框 ztStyle.setBorderBottom(BorderStyle.THIN);// 下边框 ztStyle.setBorderLeft(BorderStyle.THIN);// 左边框 ztStyle.setBorderRight(BorderStyle.THIN);// 右边框 ztStyle.setBorderTop(BorderStyle.THIN); // 上边框 HSSFCellStyle namestyle = workbook.createCellStyle(); namestyle.setAlignment(HorizontalAlignment.CENTER);// 水平居中 namestyle.setVerticalAlignment(VerticalAlignment.CENTER);// 垂直居中 namestyle.setBorderBottom(BorderStyle.THIN);// 下边框 namestyle.setBorderLeft(BorderStyle.THIN);// 左边框 namestyle.setBorderRight(BorderStyle.THIN);// 右边框 namestyle.setBorderTop(BorderStyle.THIN); // 上边框 for (short i = 0; i < headers.length; i++) { // 创建单元格 HSSFCell cell = row.createCell(i); row.setHeightInPoints(30); // 设置行高 sheet.createFreezePane(0, 1);// 冻结第1行 cell.setCellValue(headers[i]);// 设置每一列的值 cell.setCellStyle(ztStyle);// 样式应用到该单元格上 /** * 四个参数的含义: * * a表示要冻结的列数; * * b表示要冻结的行数; * * c表示右边区域[可见]的首列序号; * * d表示下边区域[可见]的首行序号; */ // sheet.createFreezePane(a,b,c,d); } // 遍历集合数据,产生数据行 Iterator<T> it = dataset.iterator(); int index = 0; while (it.hasNext()) { index++; row = sheet.createRow(index);// 创建第 index 行 T t = it.next(); // 利用反射,根据javabean属性的先后顺序,动态调用getXxx()方法得到属性值 Field[] fields = t.getClass().getDeclaredFields(); for (short i = 0; i < fields.length; i++) { HSSFCell cell = row.createCell(i); Field field = fields[i]; String fieldName = field.getName(); // 动态拼接getXxx获取属性值方法 如:TUserLand类 loginname 动态获取 -》 getLoginname 这个方法名 String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1); try { Class<? extends Object> tclass = t.getClass(); Method getMethod = tclass.getMethod(getMethodName, new Class[] {}); Object value = getMethod.invoke(t, new Object[] {}); String textValue = null; if (value instanceof Date) { Date date = (Date) value; SimpleDateFormat sdf = new SimpleDateFormat(pattern); textValue = sdf.format(date); } else if (fieldName.length() >= 4 && "Time".equalsIgnoreCase(fieldName.substring(fieldName.length() - 4))) { textValue = DateFormatUtils.getStringByTimestampAndParm((Long) value, "YYYY-MM-DD"); } else { // 其它数据类型都当作字符串简单处理 textValue = value != null ? value.toString() : ""; } // 如果不是图片数据,就利用正则表达式判断textValue是否全部由数字组成 if (textValue != null) { Pattern p = Pattern.compile("^//d+(//.//d+)?$");// 正则表达式 Matcher matcher = p.matcher(textValue); if (matcher.matches()) { // 是数字当作double处理 cell.setCellValue(Double.parseDouble(textValue)); } else { cell.setCellValue(textValue); } } } catch (Exception e) { e.printStackTrace(); } finally { // 清理资源 } row.setHeightInPoints(25);// 设置行高为25(猜测单位为px) cell.setCellStyle(namestyle); // 渲染单元格 } } try { workbook.write(out); workbook.close(); } catch (IOException e) { e.printStackTrace(); } } @SuppressWarnings("unused") public Collection<T> importExcel(File file, Collection<T> dataset) throws Exception { // 装载流 POIFSFileSystem fs = new POIFSFileSystem(((MultipartFile) file).getInputStream()); HSSFWorkbook hw = new HSSFWorkbook(fs); // 获取第一个sheet页 HSSFSheet sheet = hw.getSheetAt(0); // 创建容器 //List<Map<String, Object>> ret = new ArrayList<Map<String, Object>>(); dataset = new ArrayList<T>(sheet.getLastRowNum()-1); Iterator<T> it = dataset.iterator(); // 遍历行 从下标第一行开始(去除标题) for (int i = 1; i < sheet.getLastRowNum() + 1; i++) { T t = it.next(); Field[] fields = t.getClass().getDeclaredFields(); HSSFRow row = sheet.getRow(i); if (row != null) { // 装载obj for (int k = 0; k < row.getLastCellNum(); k++) { HSSFCell cell = row.getCell(k); Field field = fields[k]; String fieldName = field.getName(); //动态拼接getXxx获取属性值方法 如:TUserLand类 loginname 动态获取 -》 setLoginname 这个方法名 String getMethodName = "set"+ fieldName.substring(0, 1).toUpperCase()+ fieldName.substring(1); Class<? extends Object> tclass = t.getClass(); Method getMethod = tclass.getMethod(getMethodName,new Class[] {}); getMethod.invoke(t, ExcelUtil.cellFormat(cell)); String textValue = null; } //ret.add(dataObj(dataset, row)); } } hw.close(); return dataset; } @SuppressWarnings("deprecation") private static String cellFormat(HSSFCell cell){ String result = new String(); if (null != cell) { switch (cell.getCellType()) { case HSSFCell.CELL_TYPE_NUMERIC: // 数字 String cellValue = new DecimalFormat("0").format(cell.getNumericCellValue()); if (cellValue.lastIndexOf("E") > -1) { cell.setCellValue(new DecimalFormat("#").format(cell.getNumericCellValue())); } String str = String.valueOf(cell); if (str.indexOf(".0") != -1 || str.indexOf("-") != -1) { if (HSSFDateUtil.isCellDateFormatted(cell)) {// 处理日期格式、时间格式 SimpleDateFormat sdf = null; if (cell.getCellStyle().getDataFormat() == HSSFDataFormat .getBuiltinFormat("h:mm")) { sdf = new SimpleDateFormat("HH:mm"); } else {// 日期 sdf = new SimpleDateFormat("yyyyMMdd"); } Date date = cell.getDateCellValue(); result = sdf.format(date); cell.setCellValue(result); } else if (cell.getCellStyle().getDataFormat() == 176) { // 处理自定义日期格式:m月d日(通过判断单元格的格式id解决,id的值是58) double value = cell.getNumericCellValue(); Date date = org.apache.poi.ss.usermodel.DateUtil.getJavaDate(value); result = DateFormatUtils.tranDate(date, "yyyyMMdd"); cell.setCellValue(result); } else if (cell.getCellStyle().getDataFormat() == 14 || cell.getCellStyle().getDataFormat() == 31) { double value = cell.getNumericCellValue(); Date date = org.apache.poi.ss.usermodel.DateUtil.getJavaDate(value); result = DateFormatUtils.tranDate(date, "yyyyMMdd"); cell.setCellValue(result); } System.out.println(result); } break; case HSSFCell.CELL_TYPE_STRING: // 字符串 // System.out.print(cell.getStringCellValue() // + " "); break; case HSSFCell.CELL_TYPE_BOOLEAN: // Boolean // System.out.println(cell.getBooleanCellValue() // + " "); break; case HSSFCell.CELL_TYPE_FORMULA: // 公式 // System.out.print(cell.getCellFormula() + " "); break; case HSSFCell.CELL_TYPE_BLANK: // 空值 // System.out.println(" "); break; case HSSFCell.CELL_TYPE_ERROR: // 故障 // System.out.println(" "); break; default: // System.out.print("未知类型 "); break; } return result; } return null; } @SuppressWarnings("unused") private static Map<String, Object> dataObj(Object obj, HSSFRow row) throws Exception { Class<?> rowClazz = obj.getClass(); Field[] fields = FieldUtils.getAllFields(rowClazz); if (fields == null || fields.length < 1) { return null; } // 容器 Map<String, Object> map = new HashMap<String, Object>(); // 注意excel表格字段顺序要和obj字段顺序对齐 (如果有多余字段请另作特殊下标对应处理) for (int j = 0; j < fields.length; j++) { map.put(fields[j].getName(), getVal(row.getCell(j))); } return map; } @SuppressWarnings("deprecation") public static String getVal(HSSFCell hssfCell) { if (hssfCell != null) { hssfCell.setCellType(Cell.CELL_TYPE_STRING); return hssfCell.getStringCellValue(); } else { return ""; } } }