POI 해석 백만행 excel 구현

10961 단어 eclispej2ee
poi의usermodelapi는 빅데이터량 excel을 읽으면 OOM을 초래할 수 있습니다. 이벤트 모델api를 사용하여 이 excel을 처리할 수 있습니다.
소량의 줄 수 excel 사용 가능
XSSFWorkbook wb = new XSSFWorkbook(inputStream);  
         XSSFSheet sheet = wb.getSheetAt(0);  
         Iterator iter = sheet.iterator();  
         boolean isfirstline = true;  
         while (iter.hasNext()) {  
             Row row = iter.next();  
             if (isfirstline) { //    
                 isfirstline = false;  
                 continue;  
             }  
              // excel, 11 , ,  
             }  
         }  

하지만 수십만 줄보다 크면 out of memory의 오류가 발생합니다.간단하다
XSSFWorkbook wb = new XSSFWorkbook(inputStream);  

메모리 넘침을 초래했습니다.해결 방법은 이벤트 모델api를 사용하여 이런 excel을 처리할 수 있는 것이다.
    new ExcelEventUserModelParse(filePath)
                    .setHandler(new ExcelEventUserModelParse.SimpleSheetContentsHandler() {
                        @Override
                        public void endRow(int rowNum) {
                            // System.out.println(row.toString());
                            if (!isEmpty.getIsEmpty()) {
                                table.add(row);
                            } else {
                                isnull.setIsEmpty(isEmpty.getIsEmpty());
                                isnull.setRowNum(isEmpty.getRowNum());
                            }
                        }
                    }).parse();

테이블은 해석된 결과입니다.
public class ExcelEventUserModelParse {
    private Logger logger = LoggerFactory.getLogger(ExcelEventUserModelParse.class);
    private String filename;
    private SheetContentsHandler handler;

    public ExcelEventUserModelParse(String filename) {
        this.filename = filename;
    }

    public ExcelEventUserModelParse setHandler(SheetContentsHandler handler) {
        this.handler = handler;
        return this;
    }

    public void parse() {
        OPCPackage pkg = null;
        InputStream sheetInputStream = null;
        try {
            pkg = OPCPackage.open(filename, PackageAccess.READ);
            XSSFReader xssfReader = new XSSFReader(pkg);
            StylesTable styles = xssfReader.getStylesTable();
            ReadOnlySharedStringsTable strings = new ReadOnlySharedStringsTable(pkg);
            sheetInputStream = xssfReader.getSheetsData().next();
            processSheet(styles, strings, sheetInputStream);
        } catch (Exception e) {
            logger.error(e.getMessage());
            throw new RuntimeException(e.getMessage(), e);
        } finally {
            if (sheetInputStream != null) {
                try {
                    sheetInputStream.close();
                } catch (IOException e) {
                    logger.error(e.getMessage());
                    throw new RuntimeException(e.getMessage(), e);
                }
            }
            if (pkg != null) {
                try {
                    pkg.close();
                } catch (IOException e) {
                    logger.error(e.getMessage());
                    throw new RuntimeException(e.getMessage(), e);
                }
            }
        }
    }

    private void processSheet(StylesTable styles, ReadOnlySharedStringsTable strings, InputStream sheetInputStream)
            throws SAXException, ParserConfigurationException, IOException {
        XMLReader sheetParser = SAXHelper.newXMLReader();

        if (handler != null) {
            sheetParser.setContentHandler(new XSSFSheetXMLHandler(styles, strings, handler, false));
        } else {
            sheetParser.setContentHandler(
                    new XSSFSheetXMLHandler(styles, strings, new SimpleSheetContentsHandler(), false));
        }

        sheetParser.parse(new InputSource(sheetInputStream));
    }

    public static class SimpleSheetContentsHandler implements SheetContentsHandler {
        private Logger logger = LoggerFactory.getLogger(SimpleSheetContentsHandler.class);
        protected ImportDecryptModel row = new ImportDecryptModel();
        protected int a = -1;
        protected JudgementModel isEmpty = new JudgementModel();

        @Override
        public void startRow(int rowNum) {
            if (rowNum == a + 1) {
                a = rowNum;
            } else {
                isEmpty.setIsEmpty(true);
                logger.error(" " + rowNum + " ");
                a = rowNum;
                isEmpty.setRowNum(rowNum);
            }
            row = new ImportDecryptModel();
        }

        @Override
        public void endRow(int rowNum) {
            logger.error(rowNum + " : " + row);
        }

        @Override
        public void cell(String cellReference, String formattedValue, XSSFComment comment) {
            if (isEmpty != null && !isEmpty.getIsEmpty()) {
                switch (cellReference.substring(0, 1)) {
                case "A":
                    row.setUserId(formattedValue);
                    break;
                case "B":
                    row.setUid(formattedValue);
                    break;
                case "C":
                    row.setUserName(formattedValue);
                    break;
                case "D":
                    row.setIdCard(formattedValue);
                    break;
                case "E":
                    row.setMobileNo(formattedValue);
                    break;
                case "F":
                    row.setBankCard(formattedValue);
                    break;
                default:
                    break;
                }
            }
        }

        @Override
        public void headerFooter(String text, boolean isHeader, String tagName) {

        }
    }

해석 작업은 모두cell() 안에 있고 속도는 약 100만 건에 20s 정도를 기록한다.관건은 메모리가 넘치지 않는다

좋은 웹페이지 즐겨찾기