基於最新的Apache POI 4.0.1
版本來總結一下寫入Excel的過程。
代碼編寫前准備-》
添加POI 4.0.1 maven依賴:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.springbootedemo</groupId> <artifactId>springboot-demo</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>springboot-demo</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.6.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.jsoup</groupId> <artifactId>jsoup</artifactId> <version>1.11.3</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.41</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.10</version> </dependency> <dependency> <groupId>commons-beanutils</groupId> <artifactId>commons-beanutils</artifactId> <version>1.8.3</version> </dependency> <!--poi --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>4.0.1</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>4.0.1</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
example-01.xlsx 文件 ,excel數據准備:
上代碼:
DataVo(封裝數據VO類)
package com.springbootemaildemo.excel.b; /** * 讀取Excel時,封裝讀取的每一行的數據 */ public class DataVo { /** * 姓名 */ private String name; /** * 年齡 */ private Integer age; public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } }
ExcelReader(主要讀取excel文件代碼類)
package com.springbootemaildemo.excel.b; import org.apache.commons.lang3.StringUtils; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.Cell; 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.xssf.usermodel.XSSFWorkbook; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.List; /** * 讀取Excel內容 */ public class ExcelReader { private static final Logger logger = LoggerFactory.getLogger(ExcelReader.class); private static final String XLS = "xls"; private static final String XLSX = "xlsx"; /** * 根據文件后綴名類型獲取對應的工作簿對象 * * @param inputStream 讀取文件的輸入流 * @param fileType 文件后綴名類型(xls或xlsx) * @return 包含文件數據的工作簿對象 * @throws IOException */ public static Workbook getWorkbook(InputStream inputStream, String fileType) throws IOException { Workbook workbook = null; if (fileType.equalsIgnoreCase(XLS)) { workbook = new HSSFWorkbook(inputStream); } else if (fileType.equalsIgnoreCase(XLSX)) { workbook = new XSSFWorkbook(inputStream); } return workbook; } /** * 讀取Excel文件內容 * * @param fileName 要讀取的Excel文件所在路徑 * @return 讀取結果列表,讀取失敗時返回null */ public static List<DataVo> readExcel(String fileName) { Workbook workbook = null; FileInputStream inputStream = null; try { // 獲取Excel后綴名 String fileType = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length()); // 獲取Excel文件 File excelFile = new File(fileName); if (!excelFile.exists()) { logger.warn("指定的Excel文件不存在!"); return null; } // 獲取Excel工作簿 inputStream = new FileInputStream(excelFile); workbook = getWorkbook(inputStream, fileType); // 讀取excel中的數據 List<DataVo> resultDataList = parseExcel(workbook); return resultDataList; } catch (Exception e) { logger.warn("解析Excel失敗,文件名:" + fileName + " 錯誤信息:" + e.getMessage()); return null; } finally { try { if (null != workbook) { workbook.close(); } if (null != inputStream) { inputStream.close(); } } catch (Exception e) { logger.warn("關閉數據流出錯!錯誤信息:" + e.getMessage()); return null; } } } /** * 解析Excel數據 * * @param workbook Excel工作簿對象 * @return 解析結果 */ private static List<DataVo> parseExcel(Workbook workbook) { List<DataVo> resultDataList = new ArrayList<>(); // 解析sheet int numberOfSheets = workbook.getNumberOfSheets(); for (int sheetNum = 0; sheetNum < numberOfSheets; sheetNum++) { Sheet sheet = workbook.getSheetAt(sheetNum); // 校驗sheet是否合法 if (sheet == null) { continue; } // 獲取第一行數據 int firstRowNum = sheet.getFirstRowNum(); Row firstRow = sheet.getRow(firstRowNum); if (null == firstRow) { logger.warn("解析Excel失敗,在第一行沒有讀取到任何數據!"); } // 解析每一行的數據,構造數據對象 int rowStart = firstRowNum + 1; int rowEnd = sheet.getPhysicalNumberOfRows(); for (int rowNum = rowStart; rowNum < rowEnd; rowNum++) { Row row = sheet.getRow(rowNum); if (null == row) { continue; } DataVo resultData = convertRowToData(row); if (null == resultData) { logger.warn("第 " + row.getRowNum() + "行數據不合法,已忽略!"); continue; } resultDataList.add(resultData); } } return resultDataList; } /** * 將單元格內容轉換為字符串 * * @param cell * @return */ private static String convertCellValueToString(Cell cell) { if (cell == null) { return null; } String returnValue = null; switch (cell.getCellType()) { case NUMERIC: //數字 Double doubleValue = cell.getNumericCellValue(); // 格式化科學計數法,取一位整數 DecimalFormat df = new DecimalFormat("0"); returnValue = df.format(doubleValue); break; case STRING: //字符串 returnValue = cell.getStringCellValue(); break; case BOOLEAN: //布爾 Boolean booleanValue = cell.getBooleanCellValue(); returnValue = booleanValue.toString(); break; case BLANK: // 空值 break; case FORMULA: // 公式 returnValue = cell.getCellFormula(); break; case ERROR: // 故障 break; default: break; } return returnValue; } /** * 提取每一行中需要的數據,構造成為一個結果數據對象 * <p> * 當該行中有單元格的數據為空或不合法時,忽略該行的數據 * * @param row 行數據 * @return 解析后的行數據對象,行數據錯誤時返回null */ private static DataVo convertRowToData(Row row) { DataVo resultData = new DataVo(); Cell cell; int cellNum = 0; // 獲取姓名 cell = row.getCell(cellNum++); String name = convertCellValueToString(cell); resultData.setName(name); // 獲取年齡 cell = row.getCell(cellNum++); String ageStr = convertCellValueToString(cell); if (StringUtils.isEmpty(ageStr)) { // 年齡為空 resultData.setAge(null); } else { resultData.setAge(Integer.parseInt(ageStr)); } return resultData; } }
MyTest(測試類)
package com.springbootemaildemo.excel.b; import org.apache.commons.collections4.CollectionUtils; import java.util.List; public class MyTest { public static void main(String[] args) { // 設定Excel文件所在路徑 String excelFileName = "E:\\files\\example-01.xlsx"; // 讀取Excel文件內容 List<DataVo> readResult = ExcelReader.readExcel(excelFileName); //TODO 可以寫相應的業務 if (CollectionUtils.isNotEmpty(readResult)) { readResult.stream().forEach(dataVo -> { System.out.println(dataVo.getName() + "-" + dataVo.getAge()); }); } } }
結果: