基於POI的Excel文件解析

1、依賴包

<dependency>
   <groupId>org.apache.poi</groupId>
   <artifactId>poi</artifactId>
   <version>3.15</version>
</dependency>

 <dependency>
   <groupId>org.apache.poi</groupId>
   <artifactId>poi-ooxml</artifactId>
   <version>3.15</version>
</dependency>

2、工具類原代碼

package com.sinotrans.iwl.fdr.acc.util;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

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.springframework.web.multipart.MultipartFile;

public class PoiExcelUtil {
 private static final String EXCEL_XLS = "xls"; 
    private static final String EXCEL_XLSX = "xlsx"; 
 
    /**
     * 判斷Excel的版本,獲取Workbook
     * @param in
     * @param filename
     * @return
     * @throws IOException
     */ 
    public static Workbook getWorkbok(InputStream in,MultipartFile file) throws IOException{ 
        Workbook wb = null; 
        if(file.getOriginalFilename().endsWith(EXCEL_XLS)){  //Excel 2003 
            wb = new HSSFWorkbook(in); 
        }else if(file.getOriginalFilename().endsWith(EXCEL_XLSX)){  // Excel 2007/2010 
            wb = new XSSFWorkbook(in); 
        } 
        return wb; 
    } 
 
    /**
     * 判斷文件是否是excel
     * @throws Exception 
     */ 
    public static void checkExcelVaild(MultipartFile file) throws IOException{ 
        if(file.isEmpty()){ 
            throw new FileNotFoundException("文件不存在"); 
        } 
        if(!(file.getOriginalFilename().endsWith(EXCEL_XLS) || file.getOriginalFilename().endsWith(EXCEL_XLSX))){ 
            throw new IOException("文件不是Excel"); 
        } 
    } 
   
    /**
  * 讀入excel文件,解析後返回
  * @param file
  * @throws IOException
  */
 public static List<String[]> readExcel(MultipartFile excelFile) throws IOException{
            // 同時支持Excel 2003、2007 
            //File excelFile = new File("d:/product.xlsx"); // 創建文件對象 
            InputStream in = excelFile.getInputStream(); // 文件流 
           
            checkExcelVaild(excelFile); 
           
            Workbook workbook = getWorkbok(in,excelFile); 
            //Workbook workbook = WorkbookFactory.create(is); // 這種方式 Excel2003/2007/2010都是可以處理的 
           
          //創建返回對象,把每行中的值作爲一個數組,所有行作爲一個集合返回
         List<String[]> list = new ArrayList<String[]>();
         if(workbook != null){
          for(int sheetNum = 0;sheetNum < workbook.getNumberOfSheets();sheetNum++){
           //獲得當前sheet工作表
              Sheet sheet = workbook.getSheetAt(sheetNum);
              if(sheet == null){
               continue;
              }
              //獲得當前sheet的開始行
              int firstRowNum  = sheet.getFirstRowNum();
              //獲得當前sheet的結束行
              int lastRowNum = sheet.getLastRowNum();
              //循環除了第一行的所有行
              for(int rowNum = firstRowNum+1;rowNum <= lastRowNum;rowNum++){
               //獲得第一行,得到每列的參數
               Row rowHead = sheet.getRow(0);
               //獲得當前行
               Row row = sheet.getRow(rowNum);
               if(rowHead == null || row == null ){
                continue;
               }
               //獲得當前行的開始列
               int firstCellNum = row.getFirstCellNum();
               //獲得當前行的列數
               int lastCellNum = row.getPhysicalNumberOfCells();
               String[] cells = new String[row.getPhysicalNumberOfCells()];
               //循環當前行
               for(int cellNum = firstCellNum; cellNum < lastCellNum;cellNum++){
                Cell cell = row.getCell(cellNum);
                            cells[cellNum] = getCellValue(cell);
               }
               list.add(cells);
              }
          }
          workbook.close();
         }
      return list;
        }
       
        @SuppressWarnings("deprecation")
  public static String getCellValue(Cell cell){
      String cellValue = "";
      if(cell == null){
       return cellValue;
      }
      //把數字當成String來讀,避免出現1讀成1.0的情況
      if(cell.getCellType() == Cell.CELL_TYPE_NUMERIC){
       cell.setCellType(Cell.CELL_TYPE_STRING);
      }
      //判斷數據的類型
            switch (cell.getCellType()){
             case Cell.CELL_TYPE_NUMERIC: //數字
                 cellValue = String.valueOf(cell.getNumericCellValue());
                 break;
             case Cell.CELL_TYPE_STRING: //字符串
                 cellValue = String.valueOf(cell.getStringCellValue());
                 break;
             case Cell.CELL_TYPE_BOOLEAN: //Boolean
                 cellValue = String.valueOf(cell.getBooleanCellValue());
                 break;
             case Cell.CELL_TYPE_FORMULA: //公式
                 cellValue = String.valueOf(cell.getCellFormula());
                 break;
             case Cell.CELL_TYPE_BLANK: //空值
                 cellValue = "";
                 break;
             case Cell.CELL_TYPE_ERROR: //故障
                 cellValue = "非法字符";
                 break;
             default:
                 cellValue = "未知類型";
                 break;
            }
      return cellValue;
     }
}

3、測試方法

 public void saveAll(MultipartFile excelFile, String contractId){
  Errors errors = new Errors();
  //碼頭合約明細必填項校驗
  if(StringUtils.isBlank(contractId)){
   errors.put("contractId","合同ID不能爲空");
  }
     List<AccContractDetailModel> allAccContractDetailModels = new ArrayList<AccContractDetailModel>();
     try {
      List<String[]> stringList = PoiExcelUtil.readExcel(excelFile);
      for(int i = 0;i<stringList.size();i++){
       String[] strings = stringList.get(i);
       AccContractDetailModel accContractDetailModel = new AccContractDetailModel();
       accContractDetailModel.setContractId(contractId);
       accContractDetailModel.setCurrencyCode(strings[0])
       accContractDetailModel.setChargeCode(strings[1]);
       allAccContractDetailModels.add(accContractDetailModel);
      }
     } catch (IOException e) {
      errors.put("file","讀取excel文件失敗");
     }
     if(!errors.isEmpty()){
            throw  new ErrorsException(errors);
        }

//往數據庫插入List數據
 }

4、postman測試案例

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章