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();
        }
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,165评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,503评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,295评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,589评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,439评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,342评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,749评论 3 387
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,397评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,700评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,740评论 2 313
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,523评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,364评论 3 314
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,755评论 3 300
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,024评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,297评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,721评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,918评论 2 336

推荐阅读更多精彩内容

  • 使用首先需要了解他的工作原理 1.POI结构与常用类 (1)创建Workbook和Sheet (2)创建单元格 (...
    长城ol阅读 8,378评论 2 25
  • 创建新工程 打开Eclipse新建一个工程 点下一步 输入名称 点完成 新建一个目录用来存在第三方库文件 选择目录...
    长新阅读 2,173评论 3 1
  • 国家电网公司企业标准(Q/GDW)- 面向对象的用电信息数据交换协议 - 报批稿:20170802 前言: 排版 ...
    庭说阅读 10,810评论 6 13
  • POI操作Excel Excel简介一个excel文件就是一个工作簿workbook,一个工作簿中可以创建多张工作...
    灰气球阅读 4,670评论 2 48
  • 「壹」 午后两点,太阳露出了灿烂的笑脸。天空呈现出湛蓝的色调,朵朵白云飘浮空中,像是让人垂涎三尺的棉花糖。 旗杆上...
    茉笙_阅读 144评论 0 2