Spring으로 개발한다면 대부분은 poi 라이브러리를 사용해서 프로젝트를 진행합니다.
poi 라이브러리는 너무 좋습니다.
엑셀을 파싱해서 데이터를 불러오기 때문입니다.
하지만 데이터의 건수가 많아지면 당연하게도 서버의 메모리의 사용률은 증가됩니다.
그로인해 서비스의 영향을 줄 수 있습니다.
우선 구글링을 통해 얻은 정보를 공유합니다.
로직의 여러 class들이 어떤 기능을 하는지는 추후 추가하도록 하겠습니다.
아래 소스는 실제 엑셀이 파싱되는 부분을 구현한겁니다.(구글링참고)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
public class ExcelSheetHandler implements SheetContentsHandler{
private int current Col = -1;
private int currRowNum = 0;
String filePath = "";
private List<List<String>> rows = new ArrayList<List<String>>(); //실제 엑셀을 파싱해서 담아지는 데이터
private List<String> row = new ArrayList<String>();
private List<String> header = new ArrayList<String>();
public static ExcelSheetHandler readExcel(File file) throws Exception{
ExcelSheetHandler sheetHandler = new ExcelSheetHandler();
try{
//org.apache.poi.openxml4j.opc.OPCPackage
OPCPackage opc = OPCPackage.open(file);
//org.apache.poi.xssf.eventusermodel.XSSFReader
XSSFReader xssfReader = new XSSFReader(opc);
//org.apache.poi.xssf.model.StylesTable
StylesTable styles = xssfReader.getStylesTable();
//org.apache.poi.xssf.eventusermodel.ReadOnlySharedStringsTable
ReadOnlySharedStringsTable strings = new ReadOnlySharedStringsTable(opc);
//엑셀의 시트를 하나만 가져오기입니다.
//여러개일경우 while문으로 추출하셔야 됩니다.
InputStream inputStream = xssfReader.getSheetsData().next();
//org.xml.sax.InputSource
InputSource inputSource = new InputSource(inputStream);
//org.xml.sax.Contenthandler
ContentHandler handle = new XSSFSheetXMLHandler(styles, strings, sheetHandler, false);
XMLReader xmlReader = SAXHelper.newXMLReader();
xmlReader.setContentHandler(handle);
xmlReader.parse(inputSource);
inputStream.close();
opc.close();
}catch(Exception e){
//에러 발생했을때 하시고 싶은 TO-DO
}
return sheetHandler
}//readExcel - end
public List<List<String>> getRows(){
return rows;
}
@Override
public void startRow(int arg0){
this.currentCol = -1;
this.currRowNum = arg0;
}
@Override
public void cell(String columnName, String value, XSSFComment var3){
int iCol = (new CellReference(columnName)).getCol();
int emptyCol = iCol - currentCol -1;
for(int i=0; i< emptyCol; i++){
row.add("");
}
currentCol = iCol;
row.add(value);
}
@Override
public void headerFooter(String arg0, boolean arg1, String arg2){
//사용안합니다.
}
@Override
public void endRow(int rowNum){
if(rowNum == 0){
header = new ArrayList(row);
}
else{
if(row.size() < hader.size()){
for(int i = row.size(); i<header.size(); i++){
row.add("");
}
}
rows.add(new ArrayList(row));
}
row.clear();
}
}
|
cs |
그럼이제 실제 구현한 class를 호출하는 로직을 만들어 보겠습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
// 엑셀 데이터 양식 example
/ A열 B열
1행 test@naver.com Seoul
2행 mouse@gmail.com Busan
3행 apple@daum.net Jeju
/
//해당 파일은 업로드파일
String filePath = "test.xlsx";
File file = new File(filePath);
ExcelSheetHandler excelSheetHandler = ExcelSheetHandler.readExcel(file);
List<List<String>> excelDatas = excelSheetHandler.getRows();
//excelDatas >>>>> [[ test@naver.com, Seoul ],[ mouse@gmail.com, Busan ], [ apple@daum.net, Jeju ]]
int iCol = 0; //컬럼 구분값
int iRow = 0; //행 구분값
for(List<String> dataRow : excelDatas){
for(String str : dataRow){
if(iCol == 0){
//test@naver.com
System.out.println(str);
}
else if(iCol == 1){
//Seoul
System.out.println(str);
}
iCol++;
}
iCol = 0;
iRow = 0;
}
|
cs |
내부 로직들의 class가 어떤 역할을 하는지는 더 조사후에 추가하도록 하겠습니다.
감사합니다.
'IT > 개발' 카테고리의 다른 글
JAVA 입력과 출력 stream (0) | 2019.10.19 |
---|---|
Spring ibatis resultMap 쿼리 2개실행 (0) | 2019.10.16 |
스프링 form태그 (0) | 2019.10.09 |
Java 파일 읽기, 파일 쓰기 (0) | 2019.10.08 |
Spring Transactional annotation (0) | 2019.09.27 |