基於Apache poi hssf對xls(excel)文件進行解析

在美團實習的過程中,馬上要做的功能有一項是前臺上傳文件後臺獲取文件對excel文件進行解析。之前做過後臺從DB獲取數據按照模板將查詢的數據填入xls並返回給前臺提供下載的功能,最後會給出一個工具類,裏面包含這個功能的實現。

實現對excel文件的讀寫,比較主流的做法是使用Apache POI提供的各種類和方法,對Apache POI的理解可以參照這篇文章:POI基礎

在對POI有足夠的認識和理解後,可以預想對前臺上傳的文件進行解析,實際上就是在服務器端打開該文件,遍歷裏面的數據,將Excel裏面存儲的數據按照合適的對應關係存入正確的data object的field。接下來想做什麼都可以了,不管是存儲數據到DB或者進行相應的計算的都可以。感覺其實excel文件的結構通過POI提供的類來組織的話還比較簡單,宏觀的看其實一個Excel文件就是一個HSSFWorkbook類的實例,文件裏的多個sheet各自對應HSSFSheet實例,每個sheet裏面的一行行記錄對應HSSFRow,一個個單元格就是一個個HSSFCell。

那麼下面我將自己認爲最主要的代碼實現,在網上看到的,我做了一些修改。粘貼如下:

解析excel文件核心代碼
public class PoiExcelParser { 
    private Sheet sheet;    //表格類實例 
    LinkedList[] result;    //保存每個單元格的數據 ,是容器就好,看需求吧 
   
    //讀取excel文件,創建表格實例 
    private void loadExcel(String filePath) { 
        FileInputStream inStream = null
        try 
            inStream = new FileInputStream(new File(filePath)); 
            Workbook workBook = WorkbookFactory.create(inStream); 
            sheet = workBook.getSheetAt(0);     //注意sheet以0開始計數          
        catch (Exception e) { 
            e.printStackTrace(); 
        }finally
            try 
                if(inStream!=null){ 
                    inStream.close();   //關閉stream
                }                 
            catch (IOException e) {                 
                e.printStackTrace(); 
            
        
    
    //獲取某個單元格的值,統一以字符串形式返回 
    private String getCellValue(Cell cell) { 
        String cellValue = ""
        DataFormatter formatter = new DataFormatter(); 
        if (cell != null) { 
            //判斷單元格數據的類型,不同類型調用不同的方法 
            switch (cell.getCellType()) { 
                //數值類型 
                case Cell.CELL_TYPE_NUMERIC: 
                    //進一步判斷 ,單元格格式是日期格式  
                    if (DateUtil.isCellDateFormatted(cell)) { 
                        cellValue = formatter.formatCellValue(cell); 
                    else 
                        //數值 
                        double value = cell.getNumericCellValue(); 
                        int intValue = (int) value; 
                        cellValue = value - intValue == 0 ? String.valueOf(intValue) : String.valueOf(value); 
                    
                    break
                case Cell.CELL_TYPE_STRING: 
                    cellValue = cell.getStringCellValue(); 
                    break
                case Cell.CELL_TYPE_BOOLEAN: 
                    cellValue = String.valueOf(cell.getBooleanCellValue()); 
                    break
                    //判斷單元格是公式格式,需要做一種特殊處理來得到相應的值 
                case Cell.CELL_TYPE_FORMULA: 
                    try
                        cellValue = String.valueOf(cell.getNumericCellValue()); 
                    }catch(IllegalStateException e){ 
                        cellValue = String.valueOf(cell.getRichStringCellValue()); 
                    
                    break
                case Cell.CELL_TYPE_BLANK: 
                    cellValue = ""
                    break
                case Cell.CELL_TYPE_ERROR: 
                    cellValue = ""
                    break
                default
                    cellValue = cell.toString().trim(); 
                    break
            
        
        return cellValue.trim(); 
    
   
   
   
    //初始化表格中的每一行,並得到每一個單元格的值 
    public void getData(){ 
        int rowNum = sheet.getLastRowNum() + 1;
        result = new LinkedList[rowNum]; 
        for(int i=0;i<rowNum;i++){ 
            Row row = sheet.getRow(i); 
            //每有新的一行,創建一個新的LinkedList對象 
            result[i] = new LinkedList(); 
            for(int j=0;j<row.getLastCellNum();j++){ 
                Cell cell = row.getCell(j); 
                //獲取單元格的值 
                String str = getCellValue(cell); 
                //將得到的值放入鏈表中,實際的使用過程中,也可以保存在dataobject裏 
                result[i].add(str); 
            
        
    }     

這段代碼在實際工程中使用需謹慎,確保可用性,可能會做出相應的修改以適應工程的實際需要。

Update:

1.發現一個問題,就是作爲解析前臺上傳的文件,控制用戶上傳的文件格式有一定難度,而前面用hssf實現的功能只對xls格式支持,如果萬一用戶上傳的是xlsx就有問題。。。而這個問題,在很久之前就被很好的利用多態解決了,帖子鏈接如下:通過POI統一讀取Excel文件(兼容97-2003和2007+兩種格式)


 

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