分享一個操作excel的工具類,這個工具分3個部分,
ExcelUtil.java //工具類
ExcelSheetPO.java //實體對象
ExcelVersion.java //版本枚舉
可以把excel數據讀取到內存中,轉換為 List<List<Object>>,也可以根據List<List<Object>>轉化成excel文件
依賴的jar包是poi,有用到spring框架的集合工具類,不能依賴的可以動手改改
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> </dependency>
ExcelUtil.java
import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.text.DecimalFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import org.apache.commons.collections.CollectionUtils; 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.Cell; import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.CellValue; import org.apache.poi.ss.usermodel.Font; import org.apache.poi.ss.usermodel.FormulaEvaluator; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.util.CellRangeAddress; import org.apache.poi.ss.util.WorkbookUtil; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import com.zkingsoft.common.tools.FileUtil; /** * 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 final HashMap<String, CellStyle> cellStyleMap = new HashMap<>(); /** * 讀取excel文件里面的內容 支持日期,數字,字符,函數公式,布爾類型 * * @author JIANGYOUYAO * @email 935090232@qq.com * @date 2017年12月20日 * @param file * @param rowCount * @param columnCount * @return * @throws FileNotFoundException * @throws IOException */ public static List<ExcelSheetPO> readExcel(File file, Integer rowCount, Integer columnCount) throws FileNotFoundException, IOException { // 根據后綴名稱判斷excel的版本 String extName = FileUtil.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<ExcelSheetPO> sheetPOs = new ArrayList<>(); // 解析sheet for (int i = 0; i < wb.getNumberOfSheets(); i++) { Sheet sheet = wb.getSheetAt(i); List<List<Object>> 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<Object> rowValue = new LinkedList<Object>(); // 解析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) { DecimalFormat df = new DecimalFormat("0");// 格式化 number // 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文件 * * @author JIANGYOUYAO * @email 935090232@qq.com * @date 2017年12月20日 * @param version * @param excelSheets * @param filePath * @throws IOException */ public static void createWorkbookAtDisk(ExcelVersion version, List<ExcelSheetPO> excelSheets, String filePath) throws IOException { FileOutputStream fileOut = new FileOutputStream(filePath); createWorkbookAtOutStream(version, excelSheets, fileOut, true); } /** * 把excel表格寫入輸出流中,輸出流會被關閉 * * @author JIANGYOUYAO * @email 935090232@qq.com * @date 2017年12月20日 * @param version * @param excelSheets * @param outStream * @param closeStream * 是否關閉輸出流 * @throws IOException */ public static void createWorkbookAtOutStream(ExcelVersion version, List<ExcelSheetPO> 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<ExcelSheetPO> excelSheets) { Workbook wb = createWorkbook(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); 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<List<Object>> dataList = excelSheetPO.getDataList(); for (int i = 0; i < dataList.size() && i < version.getMaxRow(); i++) { List<Object> 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); cell.setCellStyle(getStyle(STYLE_DATA, wb)); cell.setCellValue(values.get(j).toString()); } } } 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)); // 限制最大列數 int column = excelSheetPO.getDataList().size() > version.getMaxColumn() ? version.getMaxColumn() : excelSheetPO.getDataList().size(); sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, column - 1)); } private static CellStyle getStyle(String type, Workbook wb) { 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 createWorkbook(ExcelVersion version) { switch (version) { case V2003: return new HSSFWorkbook(); case V2007: return new XSSFWorkbook(); } return null; } }
ExcelSheetPO.java
package com.zkingsoft.common.tools.excel; import java.util.List; /** * 定義表格的數據對象 * @author JIANGYOUYAO * @email 935090232@qq.com * @date 2017年12月20日 */ public class ExcelSheetPO { /** * sheet的名稱 */ private String sheetName; /** * 表格標題 */ private String title; /** * 頭部標題集合 */ private String[] headers; /** * 數據集合 */ private List<List<Object>> dataList; public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String[] getHeaders() { return headers; } public void setHeaders(String[] headers) { this.headers = headers; } public List<List<Object>> getDataList() { return dataList; } public void setDataList(List<List<Object>> dataList) { this.dataList = dataList; } public String getSheetName() { return sheetName; } public void setSheetName(String sheetName) { this.sheetName = sheetName; } }
ExcelVersion.java
package com.zkingsoft.common.tools.excel; /** * excel版本枚舉 * * @author JIANGYOUYAO * @email 935090232@qq.com * @date 2017年12月20日 */ public enum ExcelVersion { /** * 雖然V2007版本支持最大支持1048575 * 16383 , * V2003版支持65535*255 * 但是在實際應用中如果使用如此龐大的對象集合會導致內存溢出, * 因此這里限制最大為10000*100,如果還要加大建議先通過單元測試進行性能測試。 * 1000*100 全部導出預計時間為27s左右 */ V2003(".xls", 10000, 100), V2007(".xlsx", 100, 100); private String suffix; private int maxRow; private int maxColumn; ExcelVersion(String suffix, int maxRow, int maxColumn) { this.suffix = suffix; this.maxRow = maxRow; this.maxColumn = maxColumn; } public String getSuffix() { return this.suffix; } public int getMaxRow() { return maxRow; } public void setMaxRow(int maxRow) { this.maxRow = maxRow; } public int getMaxColumn() { return maxColumn; } public void setMaxColumn(int maxColumn) { this.maxColumn = maxColumn; } public void setSuffix(String suffix) { this.suffix = suffix; } }
如果有改進的地方歡迎留言