5、poi usermodel讀取數據

需求:讀excel中的數據,去掉空行,入庫
常用的讀取數據方法當然是用poi了,循環sheet頁,每一行row,每一個單元格cell。獲得的數據再通過反射封裝到對象中。
遇到的坑有:
(1)空行問題:具體情況具體處理吧,如果某一個的每個單元格如果都為空就認為是空行,也有某個單元格為空,就忽略該行的情況。
(2)性能問題:100條左右的數據,從讀取數據到封裝入庫,總共花了20多秒,結果當然是poi速度太慢,雖然是小系統,但是這種速度也是不可忍受的。于是找到eventUserModel方式讀取,見下一節

import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.commons.io.FileUtils;
import org.apache.poi.EncryptedDocumentException;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
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.ss.usermodel.WorkbookFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.picc.ermss.controller.UploadController;
import com.picc.ermss.model.Require;
import com.picc.ermss.model.UserSheet;

public class ExcelUtil {
    private final static Logger logger = LoggerFactory.getLogger(UploadController.class);

    public static Map<String, List<String>> readSheetTitle(File file) {
        Map<String, List<String>> sheetTitleMap = new HashMap<String, List<String>>();
        Workbook workbook = null;
        try {
            // 獲取 workbook
            workbook = WorkbookFactory.create(FileUtils.openInputStream(file));
            // 遍歷 workbook
            for (int i=0; i<workbook.getNumberOfSheets(); i++) {
                // 獲取某個sheet
                Sheet sheet = workbook.getSheetAt(i);
                List<String> titleList = new ArrayList<String>(); 
                // 獲取 sheet的第一行 表頭
                Row firstRow = sheet.getRow(0);
                if(firstRow == null) {
                    continue;
                }
                // 遍歷第一行的每個cell
                for (int j=0; j<firstRow.getLastCellNum(); j++) {
                    Cell cell = firstRow.getCell(j);
                    String title = cell.getStringCellValue().trim();
                    if (!"".equals(title)) {
                        // 標題不為空,才添加到 titleList
                        titleList.add(title);
                    }
                }
                sheetTitleMap.put(sheet.getSheetName(), titleList);
            }
        } catch (IOException | EncryptedDocumentException | InvalidFormatException e) {
            logger.info(e.getMessage());
        } finally {
            try {
                if(workbook != null) {
                    workbook.close();
                }
            } catch (IOException e) {
                logger.error(e.getMessage());
            }
        }
        return sheetTitleMap;
    }
    
    private static Sheet sheet = null;
    private static Row rowFirst = null;
    private static Row row = null;
    private static Map<String, String> objectMap = new HashMap<String, String>(); 
    private static String title = "";
    private static String value = "";
    
    // 解析excel,返回List<Map<String, String>>格式的對象
    public static List<Map<String, String>> parseExcelData(List<UserSheet> userSheetListChanged, File file) {
        logger.info("開始方法-----解析excel成List<Map<String, String>>對象");
        logger.info("獲取workbook");
        List<Map<String, String>> resultList = new LinkedList<Map<String, String>>();  
        Workbook workbook = null;
        // 獲取 workbook
        try {
            workbook = WorkbookFactory.create(FileUtils.openInputStream(file));
        } catch (EncryptedDocumentException | InvalidFormatException | IOException e) {
            e.printStackTrace();
        }
        logger.info("開始解析數據,并添加到list中");
        for (UserSheet userSheet : userSheetListChanged) {
            // 根據名字獲取sheet
            logger.info("要解析的sheetname:" + userSheet.getSheetname());
            sheet = workbook.getSheet(userSheet.getSheetname());
            // 獲取第一行
            rowFirst = sheet.getRow(0);
            // 遍歷每一行sheet.getPhysicalNumberOfRows()
            for(int rowIndex = 1; rowIndex < sheet.getPhysicalNumberOfRows(); rowIndex++) {
                logger.info("遍歷第" + rowIndex + "行");
                row = sheet.getRow(rowIndex);
                // 每一行 對應一個 ObjectMap
                objectMap.clear();
                // 遍歷數據行里的每一個單元格,遍歷長度以第一行為準
                for(int cellIndex=0;cellIndex < rowFirst.getPhysicalNumberOfCells();cellIndex++){ //cell  
                    title = rowFirst.getCell(cellIndex).getStringCellValue();
                    // 給sheetid賦值
                    if("sheetid".equals(title)) {
                        value = userSheet.getSheetid();
                    }
                    // 給serialno賦值
                    if("serialno".equals(title)) {
                        value = String.valueOf(rowIndex);
                    }
                    Cell cell = row.getCell(cellIndex);  
                    if(cell != null) {
                        cell.setCellType(Cell.CELL_TYPE_STRING);
                        value = cell.getStringCellValue();
                    }
                    // 把每個單元格里的值都放到map里
                    objectMap.put(title, value);
                } 
                // 過濾空行
                Set<Entry<String,String>> entrySet = objectMap.entrySet();
                int sum = 0;
                int actualSum = entrySet.size();
                for(Entry<String,String> entry : entrySet) {
                    String value = entry.getValue();
                    if("".equals(value) || value == null) {
                        sum += 1;
                    }
                }
                if(actualSum - sum == 2) {
                    //resultList.add(objectMap);  
                    break;
                } else {
                    resultList.add(objectMap);  
                }
            }
        }
        logger.info("結束方法-----解析excel成List<Map<String, String>>對象");
        return resultList;
    }

    
    
    /** 
     * 利用反射將    List<Map<String,String>>結構 生成相應的List<T>數據 
     *  
     * */  
    public static <T> List<T> toObjectList(List<Map<String, String>> list, Class<T> clazz) {  
        List<T> returnList = new LinkedList<T>();  
        for(int i=0; i<list.size(); i++){  
            Set<Map.Entry<String, String>> set =  list.get(i).entrySet();  
            Iterator<Entry<String, String>> iterator = set.iterator();  
            // 生成一個對象實例
            T obj = null;
            try {
                obj = clazz.newInstance();
            } catch (InstantiationException | IllegalAccessException e) {
                e.printStackTrace();
            }  
            Method[] methods = clazz.getDeclaredMethods();  
            while (iterator.hasNext()) {      
                Map.Entry<String, String> entry = (Map.Entry<String, String>) iterator.next();  
                for(Method m : methods){  
                    if(m.getName().startsWith("set")) {     
                        String methodName = entry.getKey().toString();  
                        StringBuffer sb = new StringBuffer(methodName);    
                        sb.replace(0, 1, (methodName.charAt(0)+"").toUpperCase());    
                        // 獲取set方法
                        methodName = "set" +  sb.toString();  
                        if(methodName.equals(m.getName())) {  
                            try {
                                // 調用set方法,給對象賦值
                                m.invoke(obj, entry.getValue());
                            } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
                                e.printStackTrace();
                            }  
                            break;  
                        }  
                    }  
                }  
            }  
            returnList.add(obj);  
        }  
        System.out.println("size=" + returnList.size());  
        return returnList;  
    }  
    
    
    
    public static void main(String[] args) {
//      System.out.println(ExcelUtil.class.getResource("/").getPath().substring(1));
//      File file = new File("C:/Users/Administrator/Desktop/說明文檔2/xxxx.xlsx");
//      System.out.println(readSheetTitle_HSSF(file));
        
        
        List<UserSheet> usersheetList = new ArrayList<UserSheet>();
        UserSheet sheet = new UserSheet();
        sheet.setSheetid("024e1efd-0c2b-4484-b807-e12ce9f0263a");
        sheet.setSheetname("需求提驗升級時間");
        usersheetList.add(sheet);
        File file = new File("D:/profiles/sts-bundle/workspace20170628/ermss/target/classes/aaa.xlsx");
        
        List<Map<String, String>> list = parseExcelData(usersheetList, file);
        System.out.println(list);
        try {
            System.out.println(toObjectList(list, Require.class));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 使用首先需要了解他的工作原理 1.POI結構與常用類 (1)創建Workbook和Sheet (2)創建單元格 (...
    長城ol閱讀 8,553評論 2 25
  • 創建新工程 打開Eclipse新建一個工程 點下一步 輸入名稱 點完成 新建一個目錄用來存在第三方庫文件 選擇目錄...
    長新閱讀 2,236評論 3 1
  • 國家電網公司企業標準(Q/GDW)- 面向對象的用電信息數據交換協議 - 報批稿:20170802 前言: 排版 ...
    庭說閱讀 11,166評論 6 13
  • POI操作Excel Excel簡介一個excel文件就是一個工作簿workbook,一個工作簿中可以創建多張工作...
    灰氣球閱讀 4,752評論 2 48
  • 「壹」 午后兩點,太陽露出了燦爛的笑臉。天空呈現出湛藍的色調,朵朵白云飄浮空中,像是讓人垂涎三尺的棉花糖。 旗桿上...
    茉笙_閱讀 168評論 0 2