package cc.mrbird.febs.common.utils.excl; import cn.hutool.core.util.ArrayUtil; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.ArrayUtils; import org.apache.poi.hssf.usermodel.HSSFCellStyle; import org.apache.poi.hssf.usermodel.HSSFDateUtil; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.*; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.ss.util.WorkbookUtil; import org.apache.poi.xssf.streaming.SXSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import java.io.*; import java.text.DecimalFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedList; import java.util.List; /** * excel工具类 提供读取和写入excel的功能 * * @author JIANGYOUYAO * @email 935090232@qq.com * @date 2017年12月20日 */ public class ExcelUtil { /** * 标题样式 */ private final static String STYLE_HEADER = "header"; /** * 表头样式 */ private final static String STYLE_TITLE = "title"; /** * 数据样式 */ private final static String STYLE_DATA = "data"; private static String getFileExtName(File file) { String fileName = file.getName(); String prefix = fileName.substring(fileName.lastIndexOf(".") ); return prefix; } /** * 读取excel文件里面的内容 支持日期,数字,字符,函数公式,布尔类型 * * @param file * @param rowCount * @param columnCount * @return * @throws FileNotFoundException * @throws IOException * @author JIANGYOUYAO * @email 935090232@qq.com * @date 2017年12月20日 */ public static List readExcel(File file, Integer rowCount, Integer columnCount) throws FileNotFoundException, IOException { // 根据后缀名称判断excel的版本 String extName = getFileExtName(file); Workbook wb = null; if (ExcelVersion.V2003.getSuffix().equals(extName)) { wb = new HSSFWorkbook(new FileInputStream(file)); } else if (ExcelVersion.V2007.getSuffix().equals(extName)) { wb = new XSSFWorkbook(new FileInputStream(file)); } else { // 无效后缀名称,这里之能保证excel的后缀名称,不能保证文件类型正确,不过没关系,在创建Workbook的时候会校验文件格式 throw new IllegalArgumentException("Invalid excel version"); } // 开始读取数据 List sheetPOs = new ArrayList<>(); // 解析sheet for (int i = 0; i < wb.getNumberOfSheets(); i++) { Sheet sheet = wb.getSheetAt(i); List> dataList = new ArrayList<>(); ExcelSheetPO sheetPO = new ExcelSheetPO(); sheetPO.setSheetName(sheet.getSheetName()); sheetPO.setDataList(dataList); int readRowCount = 0; if (rowCount == null || rowCount > sheet.getPhysicalNumberOfRows()) { readRowCount = sheet.getPhysicalNumberOfRows(); } else { readRowCount = rowCount; } // 解析sheet 的行 for (int j = sheet.getFirstRowNum(); j < readRowCount; j++) { Row row = sheet.getRow(j); if (row == null) { continue; } if (row.getFirstCellNum() < 0) { continue; } int readColumnCount = 0; if (columnCount == null || columnCount > row.getLastCellNum()) { readColumnCount = (int) row.getLastCellNum(); } else { readColumnCount = columnCount; } List rowValue = new LinkedList(); // 解析sheet 的列 for (int k = 0; k < readColumnCount; k++) { Cell cell = row.getCell(k); rowValue.add(getCellValue(wb, cell)); } dataList.add(rowValue); } sheetPOs.add(sheetPO); } return sheetPOs; } private static Object getCellValue(Workbook wb, Cell cell) { Object columnValue = null; if (cell != null) { // 格式化 number DecimalFormat df = new DecimalFormat("0"); // String // 字符 // 格式化日期字符串 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 格式化数字 DecimalFormat nf = new DecimalFormat("0.00"); switch (cell.getCellType()) { case Cell.CELL_TYPE_STRING: columnValue = cell.getStringCellValue(); break; case Cell.CELL_TYPE_NUMERIC: if ("@".equals(cell.getCellStyle().getDataFormatString())) { columnValue = df.format(cell.getNumericCellValue()); } else if ("General".equals(cell.getCellStyle().getDataFormatString())) { columnValue = nf.format(cell.getNumericCellValue()); } else { columnValue = sdf.format(HSSFDateUtil.getJavaDate(cell.getNumericCellValue())); } break; case Cell.CELL_TYPE_BOOLEAN: columnValue = cell.getBooleanCellValue(); break; case Cell.CELL_TYPE_BLANK: columnValue = ""; break; case Cell.CELL_TYPE_FORMULA: // 格式单元格 FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator(); evaluator.evaluateFormulaCell(cell); CellValue cellValue = evaluator.evaluate(cell); columnValue = cellValue.getNumberValue(); break; default: columnValue = cell.toString(); } } return columnValue; } /** * 在硬盘上写入excel文件 * * @param version * @param excelSheets * @param filePath * @throws IOException * @author JIANGYOUYAO * @email 935090232@qq.com * @date 2017年12月20日 */ public static void createWorkbookAtDisk(ExcelVersion version, List excelSheets, String filePath) throws IOException { FileOutputStream fileOut = new FileOutputStream(filePath); createWorkbookAtOutStream(version, excelSheets, fileOut, true); } /** * 把excel表格写入输出流中 * * @param version * @param excelSheets * @param outStream * @param closeStream 是否关闭输出流 * @throws IOException * @author JIANGYOUYAO * @email 935090232@qq.com * @date 2017年12月20日 */ public static void createWorkbookAtOutStream(ExcelVersion version, List excelSheets, OutputStream outStream, boolean closeStream) throws IOException { if (CollectionUtils.isNotEmpty(excelSheets)) { Workbook wb = createWorkBook(version, excelSheets); wb.write(outStream); if (closeStream) { outStream.close(); } } } private static Workbook createWorkBook(ExcelVersion version, List excelSheets) { Workbook wb = getWorkbookInstance(version); for (int i = 0; i < excelSheets.size(); i++) { ExcelSheetPO excelSheetPO = excelSheets.get(i); if (excelSheetPO.getSheetName() == null) { excelSheetPO.setSheetName("sheet" + i); } // 过滤特殊字符 Sheet tempSheet = wb.createSheet(WorkbookUtil.createSafeSheetName(excelSheetPO.getSheetName())); buildSheetData(wb, tempSheet, excelSheetPO, version); } return wb; } private static void buildSheetData(Workbook wb, Sheet sheet, ExcelSheetPO excelSheetPO, ExcelVersion version) { sheet.setDefaultRowHeight((short) 400); // sheet.setDefaultColumnWidth((short) 10); sheet.autoSizeColumn(1); createTitle(sheet, excelSheetPO, wb, version); createHeader(sheet, excelSheetPO, wb, version); createBody(sheet, excelSheetPO, wb, version); } private static void createBody(Sheet sheet, ExcelSheetPO excelSheetPO, Workbook wb, ExcelVersion version) { List> dataList = excelSheetPO.getDataList(); for (int i = 0; i < dataList.size() && i < version.getMaxRow(); i++) { List values = dataList.get(i); Row row = sheet.createRow(2 + i); for (int j = 0; j < values.size() && j < version.getMaxColumn(); j++) { Cell cell = row.createCell(j); Object value = values.get(j); if (value == null) { value = ""; } cell.setCellValue(String.valueOf(value)); } } } private static void createHeader(Sheet sheet, ExcelSheetPO excelSheetPO, Workbook wb, ExcelVersion version) { String[] headers = excelSheetPO.getHeaders(); Row row = sheet.createRow(1); for (int i = 0; i < headers.length && i < version.getMaxColumn(); i++) { Cell cellHeader = row.createCell(i); cellHeader.setCellStyle(getStyle(STYLE_HEADER, wb)); cellHeader.setCellValue(headers[i]); } } private static void createTitle(Sheet sheet, ExcelSheetPO excelSheetPO, Workbook wb, ExcelVersion version) { Row titleRow = sheet.createRow(0); Cell titleCel = titleRow.createCell(0); titleCel.setCellValue(excelSheetPO.getTitle()); titleCel.setCellStyle(getStyle(STYLE_TITLE, wb)); // 限制最大列数 if (ArrayUtil.isNotEmpty(excelSheetPO.getHeaders())) { int column = excelSheetPO.getHeaders().length > version.getMaxColumn() ? version.getMaxColumn() : excelSheetPO.getHeaders().length; sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, column - 1)); } } private static CellStyle getStyle(String type, Workbook wb) { HashMap cellStyleMap = new HashMap<>(); if (cellStyleMap.containsKey(type)) { return cellStyleMap.get(type); } // 生成一个样式 CellStyle style = wb.createCellStyle(); // style.setBorderBottom(HSSFCellStyle.BORDER_THIN); // style.setBorderLeft(HSSFCellStyle.BORDER_THIN); // style.setBorderRight(HSSFCellStyle.BORDER_THIN); // style.setBorderTop(HSSFCellStyle.BORDER_THIN); style.setWrapText(true); if (STYLE_HEADER == type) { style.setAlignment(HSSFCellStyle.ALIGN_CENTER); Font font = wb.createFont(); font.setFontHeightInPoints((short) 16); font.setBoldweight(Font.BOLDWEIGHT_BOLD); style.setFont(font); } else if (STYLE_TITLE == type) { style.setAlignment(HSSFCellStyle.ALIGN_CENTER); Font font = wb.createFont(); font.setFontHeightInPoints((short) 18); font.setBoldweight(Font.BOLDWEIGHT_BOLD); style.setFont(font); } else if (STYLE_DATA == type) { style.setAlignment(HSSFCellStyle.ALIGN_LEFT); Font font = wb.createFont(); font.setFontHeightInPoints((short) 12); style.setFont(font); } cellStyleMap.put(type, style); return style; } private static Workbook getWorkbookInstance(ExcelVersion version) { switch (version) { case V2003: return new HSSFWorkbook(); case V2007: return new XSSFWorkbook(); case V_BIGDATA: return new SXSSFWorkbook(2000); default: throw new IllegalArgumentException("param is not defind"); } } }