把Excel解析成List
阿新 • • 發佈:2021-01-06
0x01 作用
把有固定格式的Excel解析成List,方便操作
0x02 使用到的包 (Maven)
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>RELEASE</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>RELEASE</version> </dependency>
0x03 程式碼
public class ExcelAnalysisUtils<T> { /** * Date包名 */ private final String TYPE_DATE = "java.util.Date"; /** * Double包名 */ private final String TYPE_DOUBLE = "java.lang.Double"; /** * Integer包名 */ private final String TYPE_INTEGER = "java.lang.Integer"; /** * String包名 */ private final String TYPE_STRING = "java.lang.String"; /** * Excel匯出為實體 * * @param is is流 * @param fileName 檔名稱 * @param clazz class * @param columnNames 列名list * @param startRow 起始行(索引從0開始) * @return * @throws Exception */ public List<T> excelToEntity(InputStream is, String fileName, Class<T> clazz, List columnNames, int startRow) throws Exception { Workbook wb = null; Sheet sheet = null; Row row = null; List<T> list = null; wb = readExcel(is, fileName); if (wb != null) { //用來存放表中資料 list = new ArrayList<T>(); //獲取第一個sheet sheet = wb.getSheetAt(0); //獲取最大行數 int rownum = sheet.getPhysicalNumberOfRows(); for (int i = startRow; i < rownum; i++) { row = sheet.getRow(i); if (row != null) { list.add((T) getFieldValueByName(columnNames, row, clazz)); } } } return list; } /** * @param colnames 欄位名 * @param row 錶行 * @param clazz class * @return 欄位值 * @MethodName : getFieldValueByName * @Description : 根據欄位名獲取欄位值 */ private T getFieldValueByName(List<String> colnames, Row row, Class<T> clazz) throws Exception { T t = clazz.newInstance(); //獲取全部欄位 Field[] fields = clazz.getDeclaredFields(); //遍歷欄位 for (Field field : fields) { //判斷欄位是否存在colnames中 if (colnames.contains(field.getName())) { //開啟強制賦值 field.setAccessible(true); //獲取值 Object val = getCellFormatValue(row.getCell(colnames.indexOf(field.getName()))); //判斷欄位對應型別,然後轉換賦值 switch (field.getType().getName()) { case TYPE_DATE: //getCellFormatValue(row.getCell(colnames.indexOf(field.getName()))).toString() field.set(t, StringUtils.isEmpty(val) ? null : VeDateUtils.strToDateLong(val.toString())); break; case TYPE_DOUBLE: //getCellFormatValue(row.getCell(colnames.indexOf(field.getName()))).toString() field.set(t, StringUtils.isEmpty(val) ? null : Double.valueOf(val.toString())); break; case TYPE_INTEGER: if (val instanceof Double) { field.set(t, StringUtils.isEmpty(val) ? null : ((Double) val).intValue()); } else { field.set(t, StringUtils.isEmpty(val) ? null : Integer.valueOf(val.toString())); } break; default: //去除小數 if (val instanceof Double) { field.set(t, String.valueOf(((Double) val).intValue())); } else { field.set(t, val); } } } } return t; } //讀取excel private Workbook readExcel(InputStream is, String fileName) throws Exception { if (fileName == null) { return null; } String extString = fileName.substring(fileName.lastIndexOf(".")); try { if (".xls".equals(extString)) { return new HSSFWorkbook(is); } else if (".xlsx".equals(extString)) { return new XSSFWorkbook(is); } else { return null; } } catch (FileNotFoundException e) { throw new Exception("檔案未找到"); } catch (IOException e) { throw new Exception("IO錯誤"); } } private Object getCellFormatValue(Cell cell) { Object cellValue = null; if (cell != null) { //判斷cell型別 switch (cell.getCellType()) { case NUMERIC: { cellValue = cell.getNumericCellValue(); break; } case FORMULA: { //判斷cell是否為日期格式 if (DateUtil.isCellDateFormatted(cell)) { //轉換為日期格式YYYY-mm-dd cellValue = cell.getDateCellValue(); } else { //數字 cellValue = cell.getNumericCellValue(); } break; } case STRING: { cellValue = cell.getStringCellValue(); break; } default: } } return cellValue; } }
0x04 使用方法
new ExcelAnalysisUtils<類>().excelToEntity(檔案流,帶格式的檔名稱,類class,Excel類對應列的欄位list,從x行開始解析內容);
- 檔案流 --> 需要解析的檔案流
- 帶格式的檔名稱 ---> xxx.xls or xxx.xlsx
- 類class --> 需要解析成的類的class
- Excel類對應列的欄位list --> 要與Excel列對應,如 Excel列順序為 名稱、年齡,則list.get(0)="name",list.get(1)="age"
- 從x行開始解析內容 --> 要從第幾行開始解析Excel,索引從0開始,即Excel中第一行行標是1,則填0,以此類推