diff --git a/excel导出.java b/excel导出.java new file mode 100644 index 0000000..5fe7841 --- /dev/null +++ b/excel导出.java @@ -0,0 +1,286 @@ +package com.infinova.oms.common.utils; + +import org.apache.poi.hssf.usermodel.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.mail.internet.MimeUtility; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.OutputStream; +import java.lang.reflect.Field; +import java.net.URLEncoder; +import java.text.SimpleDateFormat; +import java.util.*; + +/** + * Description 支持多sheet表格 + * + * @author fxb + * @Date 2018-08-23 + */ +public class ExcelUtil { + + private Logger log = LoggerFactory.getLogger(this.getClass()); + + /** + * 表格文件名 + */ + private String fileName; + /** + * 表格数据项,string为sheet名,List 为这个sheet的数据 + */ + private HashMap> data; + /** + * 每个sheet的表头,String为sheet名,String[][] 为表头项与表头项对应到object的属性名,例如:["id","对象id"] + */ + private LinkedHashMap headers; + /** + * 使用该类的一些通用函数 + */ + ExportExcelUtil exportExcelUtil; + + public ExcelUtil(String fileName, HashMap> data, LinkedHashMap headers) { + this.fileName = fileName; + this.data = data; + this.headers = headers; + this.exportExcelUtil = new ExportExcelUtil(); + } + + /** + * Description 创建表格 + * + * @return org.apache.poi.hssf.usermodel.HSSFWorkbook + * @author fxb + * @date 2018/8/23 + */ + public HSSFWorkbook createExcel() throws Exception { + try { + HSSFWorkbook workbook = new HSSFWorkbook(); + // 遍历headers创建表格 + for (String key : headers.keySet()) { + this.createSheet(workbook, key, headers.get(key), this.data.get(key)); + } + return workbook; + } catch (Exception e) { + log.error("创建表格失败:{}", e.getMessage()); + throw e; + } + } + + public void writeToResponse(HSSFWorkbook workbook, HttpServletRequest request, HttpServletResponse response) + throws Exception { + String userAgent = request.getHeader("User-Agent"); + String fileName = "Excel-" + this.fileName + ".xls"; + String encodeFileName = URLEncoder.encode(fileName, "UTF8"); + // 如果没有userAgent,则默认使用IE的方式进行编码,因为毕竟IE还是占多数的 + String rtn = "filename=\"" + encodeFileName + "\""; + if (userAgent != null) { + userAgent = userAgent.toLowerCase(); + // Opera浏览器只能采用filename* + if (userAgent.indexOf("opera") != -1) { + rtn = "filename*=UTF-8''" + encodeFileName; + } + // Safari浏览器,只能采用ISO编码的中文输出 + else if (userAgent.indexOf("safari") != -1) { + rtn = "filename=\"" + new String(fileName.getBytes("UTF-8"), "ISO8859-1") + "\""; + } + // Chrome浏览器,只能采用MimeUtility编码或ISO编码的中文输出 + else if (userAgent.indexOf("applewebkit") != -1) { + encodeFileName = MimeUtility.encodeText(fileName, "UTF8", "B"); + rtn = "filename=\"" + encodeFileName + "\""; + } + // FireFox浏览器,可以使用MimeUtility或filename*或ISO编码的中文输出 + else if (userAgent.indexOf("mozilla") != -1) { + rtn = "filename*=UTF-8''" + encodeFileName; + } + } + String headStr = "attachment; " + rtn; + response.setContentType("APPLICATION/ms-excel"); + response.setCharacterEncoding("utf-8"); + response.setHeader("Content-Disposition", headStr); + OutputStream out1 = response.getOutputStream(); + workbook.write(out1); + } + + /** + * 创建一个sheet + * + * @param workbook workbook + * @param sheetName 名称 + * @param header 表头 + * @param data 数据 + */ + private void createSheet(HSSFWorkbook workbook, String sheetName, String[][] header, List data) + throws Exception { + HSSFSheet sheet = workbook.createSheet(sheetName); + // 列数 + int cellNum = header.length; + // 单元行,单元格 + HSSFRow row; + HSSFCell cell; + // 表头单元格样式 + HSSFCellStyle columnTopStyle = this.getColumnTopStyle(workbook); + // 设置表头 + row = sheet.createRow(0); + for (int i = 0; i < cellNum; i++) { + cell = row.createCell(i); + cell.setCellStyle(columnTopStyle); + String str = header[i][1]; + cell.setCellValue(str); + // 设置列宽为表头的文字宽度+6个半角符号宽度 + sheet.setColumnWidth(i, (str.getBytes("utf-8").length + 6) * 256); + } + + int rowNum = data.size(); + if (rowNum == 0) { + return; + } + // 获取Object 属性名与field属性的映射,后面通过反射获取值来设置到cell + Field[] fields = data.get(0).getClass().getDeclaredFields(); + Map fieldMap = new HashMap<>(fields.length); + for (Field field : fields) { + field.setAccessible(true); + fieldMap.put(field.getName(), field); + } + Object object; + HSSFCellStyle cellStyle = this.getStyle(workbook); + for (int i = 0; i < rowNum; i++) { + row = sheet.createRow(i + 1); + object = data.get(i); + for (int j = 0; j < cellNum; j++) { + cell = row.createCell(j); + cell.setCellStyle(cellStyle); + this.setCell(cell, object, fieldMap, header[j][0]); + } + } + + } + + private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); + + /** + * 设置单元格,根据fieldName获取对应的Field类,使用反射得到值 + * + * @param cell + * @param obj + * @param fieldMap 属性名与Field的映射 + * @param fieldName 属性名 + */ + private void setCell(HSSFCell cell, Object obj, Map fieldMap, String fieldName) throws Exception { + //获取该属性的Field对象 + Field field = fieldMap.get(fieldName); + //通过反射获取属性的值,由于不能确定该值的类型,用下面的判断语句进行合适的转型 + Object value = field.get(obj); + if (value == null) { + cell.setCellValue(""); + } else { + switch (field.getGenericType().getTypeName()) { + case "java.lang.String": + cell.setCellValue((String) value); + break; + case "java.lang.Integer": + case "int": + cell.setCellValue((int) value); + break; + case "java.lang.Double": + case "double": + cell.setCellValue((double) value); + break; + case "java.util.Date": + cell.setCellValue(this.dateFormat.format((Date) value)); + break; + default: + cell.setCellValue(obj.toString()); + } + } + } + /** + * 设置表头单元格样式 + */ + public HSSFCellStyle getColumnTopStyle(HSSFWorkbook workbook) { + + // 设置字体 + HSSFFont font = workbook.createFont(); + // 设置字体大小 + font.setFontHeightInPoints((short) 11); + // 字体加粗 + font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); + // 设置字体名字 + font.setFontName("Courier New"); + // 设置样式; + HSSFCellStyle style = workbook.createCellStyle(); + style.setFillForegroundColor(IndexedColors.BLUE.getIndex()); + // 设置底边框; + style.setBorderBottom(HSSFCellStyle.BORDER_THIN); + // 设置底边框颜色; + style.setBottomBorderColor(HSSFColor.BLACK.index); + // 设置左边框; + style.setBorderLeft(HSSFCellStyle.BORDER_THIN); + // 设置左边框颜色; + style.setLeftBorderColor(HSSFColor.BLACK.index); + // 设置右边框; + style.setBorderRight(HSSFCellStyle.BORDER_THIN); + // 设置右边框颜色; + style.setRightBorderColor(HSSFColor.BLACK.index); + // 设置顶边框; + style.setBorderTop(HSSFCellStyle.BORDER_THIN); + // 设置顶边框颜色; + style.setTopBorderColor(HSSFColor.BLACK.index); + // 在样式用应用设置的字体; + style.setFont(font); + // 设置自动换行; + style.setWrapText(false); + // 设置水平对齐的样式为居中对齐; + style.setAlignment(HSSFCellStyle.ALIGN_CENTER); + // 设置垂直对齐的样式为居中对齐; + style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); + return style; + } + + /** + * + * Description: 数据单元格样式 + * + * @param workbook + * @return + */ + public HSSFCellStyle getStyle(HSSFWorkbook workbook) { + // 设置字体 + HSSFFont font = workbook.createFont(); + // 设置字体大小 + // font.setFontHeightInPoints((short)10); + // 字体加粗 + // font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD); + // 设置字体名字 + font.setFontName("Courier New"); + // 设置样式; + HSSFCellStyle style = workbook.createCellStyle(); + // 设置底边框; + style.setBorderBottom(HSSFCellStyle.BORDER_THIN); + // 设置底边框颜色; + style.setBottomBorderColor(HSSFColor.BLACK.index); + // 设置左边框; + style.setBorderLeft(HSSFCellStyle.BORDER_THIN); + // 设置左边框颜色; + style.setLeftBorderColor(HSSFColor.BLACK.index); + // 设置右边框; + style.setBorderRight(HSSFCellStyle.BORDER_THIN); + // 设置右边框颜色; + style.setRightBorderColor(HSSFColor.BLACK.index); + // 设置顶边框; + style.setBorderTop(HSSFCellStyle.BORDER_THIN); + // 设置顶边框颜色; + style.setTopBorderColor(HSSFColor.BLACK.index); + // 在样式用应用设置的字体; + style.setFont(font); + // 设置自动换行; + style.setWrapText(false); + // 设置水平对齐的样式为居中对齐; + style.setAlignment(HSSFCellStyle.ALIGN_CENTER); + // 设置垂直对齐的样式为居中对齐; + style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); + return style; + } + +}