import com.mwkj.common.log.LogFactory; import com.mwkj.common.log.LoggerUtil; import com.mwkj.common.resp.ResponseMessage; import com.mwkj.common.util.StringUtils; import com.mwkj.web.util.ReflectionUtils; import java.io.IOException; import java.io.OutputStream; import java.text.SimpleDateFormat; import java.util.Date; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import javax.servlet.http.HttpServletResponse; import org.apache.poi.ss.usermodel.BorderStyle; import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.Font; import org.apache.poi.ss.usermodel.HorizontalAlignment; import org.apache.poi.ss.usermodel.IndexedColors; import org.apache.poi.ss.usermodel.VerticalAlignment; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.xssf.streaming.SXSSFCell; import org.apache.poi.xssf.streaming.SXSSFRow; import org.apache.poi.xssf.streaming.SXSSFSheet; import org.apache.poi.xssf.streaming.SXSSFWorkbook; /** * 做者: * 日期:2018-04-26 * 功能:Excel導出工具類 */ public class ExcelUtils { private static LoggerUtil logger = LogFactory.getLogger(ExcelUtils.class); private static SXSSFWorkbook wb; private static CellStyle titleStyle; // 標題行樣式 private static Font titleFont; // 標題行字體 private static CellStyle dateStyle; // 日期行樣式 private static Font dateFont; // 日期行字體 private static CellStyle headStyle; // 表頭行樣式 private static Font headFont; // 表頭行字體 private static CellStyle contentStyle; // 內容行樣式 private static Font contentFont; // 內容行字體 private static String REPALCESTR = ""; // 轉爲空字符 /** * @param fileName * @param response * @param setInfo * @param hasIndex 是否添加序列號 * @throws IllegalAccessException * @throws IllegalArgumentException * @Description: 將Map裏的集合對象數據輸出Excel數據流 */ public static ResponseMessage export2Excel(String fileName, HttpServletResponse response, ExportSetInfo setInfo, boolean hasIndex) throws IOException, IllegalArgumentException, IllegalAccessException { logger.info("開始導出" + fileName + ".xlsx文件"); response.setHeader("Content-Disposition", "attachment;filename=\"" + fileName + "\""); if (null == setInfo.getObjsMap()) { wb.write(response.getOutputStream()); return ResponseMessage.successResponse(wb); } try { init(); Set<Entry<String, List>> set = setInfo.getObjsMap().entrySet(); String[] sheetNames = new String[setInfo.getObjsMap().size()]; int sheetNameNum = 0; for (Entry<String, List> entry : set) { sheetNames[sheetNameNum] = ((String) entry.getKey()); sheetNameNum++; } SXSSFSheet[] sheets = getSheets(setInfo.getObjsMap().size(), sheetNames); int sheetNum = 0; for (Entry<String, List> entry : set) { // Sheet List objs = (List) entry.getValue(); // 標題行 createTableTitleRow(setInfo, sheets, sheetNum, false); // 日期行 createTableDateRow(setInfo, sheets, sheetNum, false); // 表頭 creatTableHeadRow(setInfo, sheets, sheetNum, false); // 表體 String[] fieldNames = (String[]) setInfo.getFieldNames().get(sheetNum); int rowNum = 3; for (Object obj : objs) { SXSSFRow contentRow = sheets[sheetNum].createRow(rowNum); contentRow.setHeight((short) 300); SXSSFCell[] cells = getCells(contentRow, ((String[]) setInfo.getFieldNames().get(sheetNum)).length, false); int cellNum = hasIndex ? 1 : 0;// 去掉一列序號,所以從1開始 if (fieldNames != null) { for (int num = 0; num < fieldNames.length; num++) { Object value = null; if ((obj instanceof Map)) { value = ((Map) obj).get(fieldNames[num]); } else { value = ReflectionUtils.invokeGetterMethod(obj, fieldNames[num]); } cells[cellNum].setCellValue(value == null ? REPALCESTR : StringUtils.isBlank(value.toString()) ? REPALCESTR : value.toString()); cellNum++; } } rowNum++; } adjustColumnSize(sheets, sheetNum, fieldNames);// 自動調整列寬 sheetNum++; } wb.write(response.getOutputStream()); return ResponseMessage.successResponse(wb); } catch (Exception e) { logger.info("導出Excel異常", e); throw e; } finally { try { if (wb != null) { wb.close(); } response.getOutputStream().close(); } catch (Exception e) { logger.info("導出Excel異常", e); throw e; } } } /** * @Description: 初始化 */ private static void init() { wb = new SXSSFWorkbook(); titleFont = wb.createFont(); titleStyle = wb.createCellStyle(); dateStyle = wb.createCellStyle(); dateFont = wb.createFont(); headStyle = wb.createCellStyle(); headFont = wb.createFont(); contentStyle = wb.createCellStyle(); contentFont = wb.createFont(); initTitleCellStyle(); initTitleFont(); initDateCellStyle(); initDateFont(); initHeadCellStyle(); initHeadFont(); initContentCellStyle(); initContentFont(); } /** * @Description: 自動調整列寬 */ private static void adjustColumnSize(SXSSFSheet[] sheets, int sheetNum, String[] fieldNames) { for (int i = 0; i < fieldNames.length + 1; i++) { sheets[sheetNum].trackColumnForAutoSizing(i); sheets[sheetNum].autoSizeColumn(i, true); /* 實際寬度 */ int curColWidth = 0; /* 默認寬度 */ int[] defaultColWidth = { 2000, 2500, 3000, 3500, 4000, 4500 }; /* 實際寬度 < 默認寬度的時候、設置爲默認寬度 */ for (int j = 0; j < 6; j++) { curColWidth = sheets[sheetNum].getColumnWidth(i); if (curColWidth < defaultColWidth[j]) { sheets[sheetNum].setColumnWidth(i, defaultColWidth[j]); break; } } } } /** * @Description: 建立標題行(需合併單元格) */ private static void createTableTitleRow(ExportSetInfo setInfo, SXSSFSheet[] sheets, int sheetNum, boolean withoutRownum) { int length = ((String[]) setInfo.getFieldNames().get(sheetNum)).length; if (withoutRownum) { length -= 1; } CellRangeAddress titleRange = new CellRangeAddress(0, 0, 0, length); sheets[sheetNum].addMergedRegion(titleRange); SXSSFRow titleRow = sheets[sheetNum].createRow(0); titleRow.setHeight((short) 800); SXSSFCell titleCell = titleRow.createCell(0); titleCell.setCellStyle(titleStyle); titleCell.setCellValue(setInfo.getTitles()[sheetNum]); } /** * @Description: 建立日期行(需合併單元格) */ private static void createTableDateRow(ExportSetInfo setInfo, SXSSFSheet[] sheets, int sheetNum, boolean withoutRownum) { int length = ((String[]) setInfo.getFieldNames().get(sheetNum)).length; if (withoutRownum) { length -= 1; } CellRangeAddress dateRange = new CellRangeAddress(1, 1, 0, length); sheets[sheetNum].addMergedRegion(dateRange); SXSSFRow dateRow = sheets[sheetNum].createRow(1); dateRow.setHeight((short) 350); SXSSFCell dateCell = dateRow.createCell(0); dateCell.setCellStyle(dateStyle); dateCell.setCellValue(new SimpleDateFormat("yyyy-MM-dd").format(new Date())); } /** * @Description: 建立表頭行(需合併單元格) */ private static void creatTableHeadRow(ExportSetInfo setInfo, SXSSFSheet[] sheets, int sheetNum, boolean withoutRownum) { int num = 1; if (withoutRownum) { num = 0; } // 表頭 SXSSFRow headRow = sheets[sheetNum].createRow(2); headRow.setHeight((short) 350); if (!withoutRownum) { // 列頭名稱 SXSSFCell snCell = headRow.createCell(0); snCell.setCellStyle(headStyle); snCell.setCellValue("序號"); } int length = ((String[]) setInfo.getFieldNames().get(sheetNum)).length; // 列頭名稱 for (int i = 0; i < length; i++) { SXSSFCell headCell = headRow.createCell(num + i); headCell.setCellStyle(headStyle); headCell.setCellValue(((String[]) setInfo.getHeadNames().get(sheetNum))[i]); } } /** * @Description: 建立全部的Sheet */ private static SXSSFSheet[] getSheets(int num, String[] names) { SXSSFSheet[] sheets = new SXSSFSheet[num]; for (int i = 0; i < num; i++) { sheets[i] = wb.createSheet(names[i]); } return sheets; } /** * @Description: 建立內容行的每一列(附加一列序號) */ private static SXSSFCell[] getCells(SXSSFRow contentRow, int num, boolean withoutRownum) { if (!withoutRownum) { num += 1; } SXSSFCell[] cells = new SXSSFCell[num]; int i = 0; for (int len = cells.length; i < len; i++) { cells[i] = contentRow.createCell(i); cells[i].setCellStyle(contentStyle); } // 設置序號列值,由於出去標題行和日期行,全部-2 cells[0].setCellValue(contentRow.getRowNum() - 2); return cells; } /** * @Description: 初始化標題行樣式 */ private static void initTitleCellStyle() { titleStyle.setAlignment(HorizontalAlignment.CENTER); titleStyle.setVerticalAlignment(VerticalAlignment.CENTER); titleStyle.setFont(titleFont); titleStyle.setFillBackgroundColor(IndexedColors.SKY_BLUE.index); } /** * @Description: 初始化日期行樣式 */ private static void initDateCellStyle() { dateStyle.setAlignment(HorizontalAlignment.CENTER_SELECTION); dateStyle.setVerticalAlignment(VerticalAlignment.CENTER); dateStyle.setFont(dateFont); dateStyle.setFillBackgroundColor(IndexedColors.SKY_BLUE.index); } /** * @Description: 初始化表頭行樣式 */ private static void initHeadCellStyle() { headStyle.setAlignment(HorizontalAlignment.CENTER); headStyle.setVerticalAlignment(VerticalAlignment.CENTER); headStyle.setFont(headFont); headStyle.setFillBackgroundColor(IndexedColors.YELLOW.index); headStyle.setBorderTop(BorderStyle.MEDIUM); headStyle.setBorderBottom(BorderStyle.THIN); headStyle.setBorderLeft(BorderStyle.THIN); headStyle.setBorderRight(BorderStyle.THIN); headStyle.setTopBorderColor(IndexedColors.BLUE.index); headStyle.setBottomBorderColor(IndexedColors.BLUE.index); headStyle.setLeftBorderColor(IndexedColors.BLUE.index); headStyle.setRightBorderColor(IndexedColors.BLUE.index); } /** * @Description: 初始化內容行樣式 */ private static void initContentCellStyle() { contentStyle.setAlignment(HorizontalAlignment.CENTER); contentStyle.setVerticalAlignment(VerticalAlignment.CENTER); contentStyle.setFont(contentFont); contentStyle.setBorderTop(BorderStyle.THIN); contentStyle.setBorderBottom(BorderStyle.THIN); contentStyle.setBorderLeft(BorderStyle.THIN); contentStyle.setBorderRight(BorderStyle.THIN); contentStyle.setTopBorderColor(IndexedColors.BLUE.index); contentStyle.setBottomBorderColor(IndexedColors.BLUE.index); contentStyle.setLeftBorderColor(IndexedColors.ORANGE.index); contentStyle.setRightBorderColor(IndexedColors.BLUE.index); contentStyle.setWrapText(true); } /** * @Description: 初始化標題行字體 */ private static void initTitleFont() { titleFont.setFontName("華文楷體"); titleFont.setFontHeightInPoints((short) 20); titleFont.setBold(true); titleFont.setCharSet((byte) 1); titleFont.setColor(IndexedColors.BLUE_GREY.index); } /** * @Description: 初始化日期行字體 */ private static void initDateFont() { dateFont.setFontName("隸書"); dateFont.setFontHeightInPoints((short) 10); dateFont.setBold(true); dateFont.setCharSet((byte) 1); dateFont.setColor(IndexedColors.BLUE_GREY.index); } /** * @Description: 初始化表頭行字體 */ private static void initHeadFont() { headFont.setFontName("宋體"); headFont.setFontHeightInPoints((short) 10); headFont.setBold(true); headFont.setCharSet((byte) 1); headFont.setColor(IndexedColors.BLUE_GREY.index); } /** * @Description: 初始化內容行字體 */ private static void initContentFont() { contentFont.setFontName("宋體"); contentFont.setFontHeightInPoints((short) 10); contentFont.setCharSet((byte) 1); contentFont.setColor(IndexedColors.BLUE_GREY.index); } /** * 做者: * 日期:2018-04-26 * 功能:封裝Excel導出的設置信息 */ public static class ExportSetInfo { private LinkedHashMap<String, List> objsMap; private String[] titles; private List<String[]> headNames; private List<String[]> fieldNames; private OutputStream out; public ExportSetInfo(LinkedHashMap<String, List> objsMap, List<String[]> fieldNames, String[] titles, List<String[]> headNames, OutputStream out) { this.objsMap = objsMap; this.fieldNames = fieldNames; this.titles = titles; this.headNames = headNames; this.out = out; } public LinkedHashMap<String, List> getObjsMap() { return this.objsMap; } /** * @param-objsMap導出數據 泛型 * String : 表明sheet名稱 * List : 表明單個sheet裏的全部行數據 */ public void setObjsMap(LinkedHashMap<String, List> objsMap) { this.objsMap = objsMap; } public List<String[]> getFieldNames() { return this.fieldNames; } /** * @param-clazz對應每一個sheet裏的每行數據的對象的屬性名稱 */ public void setFieldNames(List<String[]> fieldNames) { this.fieldNames = fieldNames; } /** * @param-titles對應每一個sheet裏的標題,即頂部大字 */ public String[] getTitles() { return this.titles; } public void setTitles(String[] titles) { this.titles = titles; } public List<String[]> getHeadNames() { return this.headNames; } /** * @param headNames 對應每一個頁籤的表頭的每一列的名稱 */ public void setHeadNames(List<String[]> headNames) { this.headNames = headNames; } public OutputStream getOut() { return this.out; } /** * @param out Excel數據將輸出到該輸出流 */ public void setOut(OutputStream out) { this.out = out; } } }
/** * 導出出入統計Excel * @param dto * @param response * @return */ @RequestMapping(value = "/exportAccessStatisticsExcel", method = RequestMethod.POST) public ResponseMessage exportAccessStatisticsExcel(@RequestBody StatisticsQueryDto dto, HttpServletResponse response) { logger.info("ExportExcelController.exportAccessStatisticsExcel begin dto:" + dto); ResponseMessage resp = null; try { List<Map<String, Object>> dataList = this.prkPassRecordService.getAccessStatisticsReportList(dto); if (CollectionUtils.isEmpty(dataList)){ return ResponseMessage.createResponse(ResponseMessageCodeEnum.export_no_data,null); } String name = "出入統計列表"; String fileName = new String((dto.getCreateTimeBegin() + "_" + dto.getCreateTimeEnd() + name + ".xlsx").getBytes("gb2312"), "iso8859-1"); List<String[]> headNames = new ArrayList(); List<String[]> fieldNames = new ArrayList(); headNames.add("記錄編號,記錄類型,通行類型,通行方式,停靠車場,通行通道,車輛類型,車牌號碼,識別號碼,車牌顏色,記錄時間".split(",")); fieldNames.add("recordId,recordType,passType,passMode,parkName,gateName,vehicleType,plateNumber,recognizeNumber,plateColor,recordTime".split(",")); LinkedHashMap<String, List> map = new LinkedHashMap(); map.put(name, dataList); ExcelUtils.ExportSetInfo setInfo = new ExcelUtils.ExportSetInfo(map, fieldNames, new String[]{name}, headNames, response.getOutputStream()); resp = ExcelUtils.export2Excel(fileName, response, setInfo, true); } catch (Exception e) { e.printStackTrace(); resp = ResponseMessage.createResponse(ResponseMessageCodeEnum.export_faulted,null); } logger.info("ExportExcelController.exportAccessStatisticsExcel end dto:" + dto); return resp; }