'대용량 엑셀'에 해당되는 글 1건

  1. 2016.09.22 대용량 엑셀파일 업로드 excel upload 4

java에서는 엑셀파일을 읽을때 대용량 엑셀 같은 경우에는 메모리 이슈(out of memory)가 발생하는 경우가 많다

그래서 이번에는 대용량 엑셀파일 처리하는 걸 올릴려고 한다.


여기서 부터 실제 코딩 


//엑셀파일 읽어서 저장할 List

List<String[]> dataList = null;

OPCPackage opc = null;


opc = OPCPackage.open(file);

XSSFReader xssfReader = null;

xssfReader = new XSSFReader(opc);

XSSFReader.SheetIterator itr = (SheetIterator) xssfReader.getSheetsData();

StylesTable styles = xssfReader.getStylesTable();

ReadOnlySharedStringsTable strings = new ReadOnlySharedStringsTable(opc);

dataList = new ArrayList<String[]>();

while(itr.hasNext()){

InputStream sheetStream = itr.next();

InputSource sheetSource = new InputSource(sheetStream);

//Sheet2ListHandler은 엑셀 data를 가져와서 SheetContentHandler(Interface)를 재정의 해서 만든 Class

        //String[] 배열을 몇개 사용할지 숫자

Sheet2ListHandler sheet2ListHandler = new Sheet2ListHandler(dataList, 22);     //

ContentHandler handler = new XSSFSheetXMLHandler(styles, strings, sheet2ListHandler, true);

SAXParserFactory saxFactory = SAXParserFactory.newInstance();

SAXParser saxParser = null;;

saxParser = saxFactory.newSAXParser();

//sax parser 방식의 xmlReader를 생성

XMLReader sheetParser = saxParser.getXMLReader();

//xml reader에 row와 cell 이벤트를 생성하는 핸들러를 설정한 후.

sheetParser.setContentHandler(handler);

//위에서 Sheet 별로 생성한 inputSource를 parsing합니다.

//이 과정에서 handler는 row와 cell이벤트를 생성하고 생성된 이벤트는 sheet2ListHandler 가 받아서

처리합니다.

sheetParser.parse(sheetSource);

  sheetStream.close();

}



//Sheet2ListHandler     

public class Sheet2ListHandler implements SheetContentsHandler {


private boolean firstCellOfRow = false;

private int currentCol = -1;

//collection 객체

private List<String[]> rows;


//collection에 추가될 객체 startRow에서 초기화함

private String[] row;

//collection 내 객체를 String[]로 잡았기 때문에 배열의 길이를 생성시 받도록 설계

private int columnCnt;

//cell 이벤트 처리 시 해당 cell의 데이터가 배열 어디에 저장되야 할지 가리키는 pointer

private int currColNum = 0;

//외부 collection 과 배열 size를 받기 위해 추가한 부분입니다.

public Sheet2ListHandler(List<String[]> rows, int columnsCnt) {

this.rows = rows;

this.columnCnt = columnsCnt;

}

//Row의 시작 부분에서 발생하는 이벤트를 처리하는 method

@Override

public void startRow(int rowNum) {

this.row = new String[columnCnt];

currColNum = 0;

}


//Row의 끝에서 발생하는 이벤트를 처리하는 method

@Override

public void endRow(int rowNum) {

//cell 이벤트에서 담아놓은 row String[]를 collection에 추가

//데이터가 하나도 없는 row는 collection 추가하지 않도록 조건 추가

boolean addFlag = false;

for(String data:row){

if(!"".equals(data)){

addFlag = true;

}

}

if(addFlag)rows.add(row);

}


//cell 이벤트 발생 시 해당 cell의 주소와 값을 받아옴.

@Override

public void cell(String cellReference, String formattedValue, XSSFComment comment) {

// 엑셀 내용중 비어있는 셀은 제외하고 쓰여지기 때문에 아래와 같이 체크후 빈셀은 ""로 채워서 자리를 채워줌

int thisCol = (new CellReference(cellReference)).getCol();

int missedCols = thisCol - currentCol - 1;

   for (int i=0; i<missedCols; i++) {

       row[currColNum++] = "";

   }

   currentCol = thisCol;

  row[currColNum++] = formattedValue == null ? "":formattedValue;

    }

@Override

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

}


'Java' 카테고리의 다른 글

JAVA SPRING + MYBATIS + ORACLE TXT 파일 BLOB 형태로 DB에 INSERT  (0) 2016.11.01
java 배열 내 문자열 확인  (0) 2016.10.04
[Tomcat] UTF-8 한글 처리  (0) 2016.04.08
이클립스 jdk 경로 지정  (0) 2016.04.07
이클립스 SVN 설치  (0) 2013.07.24
Posted by 샤린냥
이전버튼 1 이전버튼