* ์ผ๋จ ์์ ์ ์ ๋์ฉ๋ ํ ์คํธ๋ฅผ ์ํ eclipse Heap ์์ญ ๋๋ฆฌ๊ธฐ
eclipse .ini ํ์ผ์ ์ด๊ธฐ Xms (์์ํฌ๊ธฐ) / Xmx (์ต๋ํฌ๊ธฐ) ์์ ํ๊ธฐ
์ฐธ๊ณ ๋ก Xmx ์ต๋ํฌ๊ธฐ๋ ์๊ธฐ์ pc ram ์ฌ์์ ํ์ธํ๊ณ ๋ฐ๊พธ๊ธฐ ์ถ์ฒ
JVM ๋ฉ๋ชจ๋ฆฌ ์ฒดํฌํ๋ ๋ฐฉ๋ฒ
// ์์
ํ์ผ ์ฒ๋ฆฌ ์ ์ ๋ฉ๋ชจ๋ฆฌ ์ํ ์ถ๋ ฅ
Runtime runtime = Runtime.getRuntime();
long memoryBefore = runtime.totalMemory() - runtime.freeMemory();
totalMemory(): JVM์ด ํ ๋นํ ์ ์ฒด ๋ฉ๋ชจ๋ฆฌ ์์ ๋ฐํ. JVM์ ์ด๊ธฐ ๋ฉ๋ชจ๋ฆฌ ํฌ๊ธฐ์ ์ต๋ ๋ฉ๋ชจ๋ฆฌ ํฌ๊ธฐ๋ฅผ ํฉ์น ๊ฐ
freeMemory(): ํ์ฌ ์ฌ์ฉ ๊ฐ๋ฅํ ๋ฉ๋ชจ๋ฆฌ ์์ ๋ฐํ. ํ์ฌ ํ ๋น๋ ๋ฉ๋ชจ๋ฆฌ ์ค์์ ์ฌ์ฉ๋์ง ์์ ์์ญ์ ํฌ๊ธฐ๋ฅผ ์๋ฏธ
์์ ํ์ผ์ฝ๊ธฐ๋ฅผ ์ํด ์ฌ์ฉํ 3๊ฐ์ง ๋ฐฉ๋ฒ
<form action="/excelUpload.do" enctype="multipart/form-data" method="post">
<input type="file" name="excelFile">
<button type="submit">Upload</button>
</form>
1. XSSFWorkbook ์ฌ์ฉ
@ResponseBody
@RequestMapping(value = "/excelUpload.do", method = RequestMethod.POST)
public void excelUpload(MultipartHttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
response.setContentType("text/html;charset=UTF-8");
try {
// ์์
ํ์ผ ์ฒ๋ฆฌ ์ ์ ๋ฉ๋ชจ๋ฆฌ ์ํ ์ถ๋ ฅ
Runtime runtime = Runtime.getRuntime();
long memoryBefore = runtime.totalMemory() - runtime.freeMemory();
System.out.println("Memory Before Processing (bytes): " + memoryBefore);
MultipartFile file = request.getFile("excelFile");
if (file != null) {
// ํ์ผ ํฌ๊ธฐ ๊ฐ์ ธ์ค๊ธฐ
File uploadedFile = new File(file.getOriginalFilename());
file.transferTo(uploadedFile);
long fileSizeBytes = uploadedFile.length(); // ํ์ผ ํฌ๊ธฐ (๋ฐ์ดํธ ๋จ์)
double fileSizeMB = fileSizeBytes / (1024.0 * 1024.0); // ํ์ผ ํฌ๊ธฐ (MB ๋จ์)
System.out.println("ํ์ผ ํฌ๊ธฐ: " + fileSizeMB + " MB");
InputStream fileContent = file.getInputStream();
XSSFWorkbook workbook = new XSSFWorkbook(fileContent);
// ํน์ ์ด๋ฆ์ ์ํธ
XSSFSheet sheet = workbook.getSheet("B");
System.out.println("sheet ::" + sheet);
int rowLength = 0;
for (Row row : sheet) {
rowLength = row.getLastCellNum();
for (Cell cell : row) {
}
}
// ์์
ํ์ผ ์ฒ๋ฆฌ ํ, ๋ฉ๋ชจ๋ฆฌ ๋ฆฌ์์ค ํด์
workbook.close();
} else {
response.getWriter().println("No file uploaded.");
}
// ์์
ํ์ผ ์ฒ๋ฆฌ ํ์ ๋ฉ๋ชจ๋ฆฌ ์ํ ์ถ๋ ฅ
long memoryAfter = runtime.totalMemory() - runtime.freeMemory();
System.out.println("Memory After Processing (bytes): " + memoryAfter);
long memoryUsed = memoryAfter - memoryBefore;
System.out.println("Memory Used (bytes): " + memoryUsed);
} catch (Exception e) {
e.printStackTrace();
response.getWriter().println("Error processing Excel file.");
}
}
2. XSSFWorkbook + opcPackage ์ฌ์ฉ
<form action="/excelUploadOpc.do" enctype="multipart/form-data" method="post">
<input type="file" name="excelFile">
<button type="submit">Upload</button>
</form>
OPCPackage๋ฅผ ์ฌ์ฉ : ์์ ํ์ผ์ OOXML(์คํ XML ๋ฌธ์) ํ์์ผ๋ก ์์ถํด์ ๊ฐ์ ธ์ด.
@ResponseBody
@RequestMapping(value = "/excelUploadOpc.do", method = RequestMethod.POST)
public void excelUploadOpc(MultipartHttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
response.setContentType("text/html;charset=UTF-8");
try {
// ์์
ํ์ผ ์ฒ๋ฆฌ ์ ์ ๋ฉ๋ชจ๋ฆฌ ์ํ ์ถ๋ ฅ
Runtime runtime = Runtime.getRuntime();
long memoryBefore = runtime.totalMemory() - runtime.freeMemory();
System.out.println("Memory Before Processing (bytes): " + memoryBefore);
MultipartFile file = request.getFile("excelFile");
if (file != null) {
// ํ์ผ ํฌ๊ธฐ ๊ฐ์ ธ์ค๊ธฐ
File uploadedFile = new File(file.getOriginalFilename());
file.transferTo(uploadedFile);
long fileSizeBytes = uploadedFile.length(); // ํ์ผ ํฌ๊ธฐ (๋ฐ์ดํธ ๋จ์)
double fileSizeMB = fileSizeBytes / (1024.0 * 1024.0); // ํ์ผ ํฌ๊ธฐ (MB ๋จ์)
System.out.println("ํ์ผ ํฌ๊ธฐ: " + fileSizeMB + " MB");
InputStream fileContent = file.getInputStream();
// OPCPackage๋ฅผ ์ฌ์ฉ : ์์
ํ์ผ์ OOXML(์คํ XML ๋ฌธ์)ํ์์ผ๋ก ์์ถํด์ ๊ฐ์ ธ์จ๋ค.
OPCPackage opcPackage = OPCPackage.open(fileContent);
XSSFWorkbook workbook = new XSSFWorkbook(opcPackage);
// ํน์ ์ด๋ฆ์ ์ํธ
XSSFSheet sheet = workbook.getSheet("B");
System.out.println("sheet ::" + sheet);
int rowLength = 0;
for (Row row : sheet) {
rowLength = row.getLastCellNum();
for (Cell cell : row) {
}
}
// ์์
ํ์ผ ์ฒ๋ฆฌ ํ, ๋ฉ๋ชจ๋ฆฌ ๋ฆฌ์์ค ํด์
workbook.close();
opcPackage.close();
} else {
response.getWriter().println("No file uploaded.");
}
// ์์
ํ์ผ ์ฒ๋ฆฌ ํ์ ๋ฉ๋ชจ๋ฆฌ ์ํ ์ถ๋ ฅ
long memoryAfter = runtime.totalMemory() - runtime.freeMemory();
System.out.println("Memory After Processing (bytes): " + memoryAfter);
long memoryUsed = memoryAfter - memoryBefore;
System.out.println("Memory Used (bytes): " + memoryUsed);
} catch (Exception e) {
e.printStackTrace();
response.getWriter().println("Error processing Excel file.");
}
}
*** 3. SAX ์ฌ์ฉ ***
๋ฐ์ดํฐ๋ฅผ ์์ฐจ์ ์ผ๋ก ์ฝ์ด ๋ด๋ ค๊ฐ๋ฉฐ ๋ ธ๋์ ์์๊ณผ ๋๋ถ๋ถ์ ์ด๋ฒคํธ๋ฅผ ๋ฐ์์ํจ๋ค.
๋ฌธ์ ์ ์ฒด๋ฅผ ๋ฉ๋ชจ๋ฆฌ์ ์ฌ๋ฆฌ์ง ์๊ธฐ ๋๋ฌธ์ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ด ์ ๊ณ ๋จ์ํ ์ฝ๊ธฐ๋ง ํ ๋ ๋น ๋ฅธ ์๋๋ฅผ ๋ณด์ธ๋ค.
<form action="/excelUploadSax.do" enctype="multipart/form-data" method="post">
<input type="file" name="excelFile">
<button type="submit">Upload</button>
</form>
@ResponseBody
@RequestMapping(value = "/excelUploadSax.do", method = RequestMethod.POST)
public void excelUploadSax(MultipartHttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
response.setContentType("text/html;charset=UTF-8");
try {
// ์์
ํ์ผ ์ฒ๋ฆฌ ์ ์ ๋ฉ๋ชจ๋ฆฌ ์ํ ์ถ๋ ฅ
Runtime runtime = Runtime.getRuntime();
long memoryBefore = runtime.totalMemory() - runtime.freeMemory();
System.out.println("Memory Before Processing (bytes): " + memoryBefore);
MultipartFile file = request.getFile("excelFile");
// ๋ฐฉ์1
// SheetHandler excelSheetHandler = ExcelSheetHandler.readExcel(file);
// ๋ฐฉ์2
SheetHandler excelSheetHandler = ExcelSheetHandler.readExcel2(file);
// ์์
ํค๋ ๊ฐ ๊ฐ์ ธ์ค๊ธฐ
List<String> excelHeader = excelSheetHandler.getHeader();
// ์์
๋ด๊ธด ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ
List<List<String>> excelDatas = excelSheetHandler.getRows();
System.out.println("excelDatas :: " + excelDatas);
System.out.println("excelHeader :: " + excelHeader);
// ์์
ํ์ผ ์ฒ๋ฆฌ ํ์ ๋ฉ๋ชจ๋ฆฌ ์ํ ์ถ๋ ฅ
long memoryAfter = runtime.totalMemory() - runtime.freeMemory();
System.out.println("Memory After Processing (bytes): " + memoryAfter);
long memoryUsed = memoryAfter - memoryBefore;
System.out.println("Memory Used (bytes): " + memoryUsed);
} catch (Exception e) {
e.printStackTrace();
response.getWriter().println("Error processing Excel file.");
}
}
์ถ๋ ฅ ๊ฒฐ๊ณผ
excelDatas :: [[2, 2, 2, 2, 2, 2, 2], [3, 3, 3, 3, 3, 3, 3], [4, 4, 4, 4, 4, 4, 4], [5, 5, 5, 5, 5, 5, 5], [6, 6, 6, 6, 6, 6, 6], [7, 7, 7, 7, 7, 7, 7], [8, 8, 8, 8, 8, 8, 8], [9, 9, 9, 9, 9, 9, 9], [10, 10, 10, 10, 10, 10, 10], [11, 11, 11, 11, 11, 11, 11], [12, 12, 12, 12, 12, 12, 12], [13, 13, 13, 13, 13, 13, 13], [14, 14, 14, 14, 14, 14, 14], [15, 15, 15, 15, 15, 15, 15]]
excelHeader :: [1, 1, 1, 1, 1, 1, 1]
ExcelSheetHandler.java
package egovframework.com.cmm.web;
import java.io.InputStream;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.util.SAXHelper;
import org.apache.poi.xssf.eventusermodel.ReadOnlySharedStringsTable;
import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler;
import org.apache.poi.xssf.model.StylesTable;
import org.springframework.web.multipart.MultipartFile;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
public class ExcelSheetHandler {
// ๋ฐฉ์ 1
public static SheetHandler readExcel(MultipartFile file) {
SheetHandler sheetHandler = new SheetHandler();
try {
// MultipartFile์์ InputStream ๊ฐ์ ธ์ค๊ธฐ
InputStream inputStream = file.getInputStream();
// InputStream์ ์ฌ์ฉํ์ฌ OPCPackage ์ด๊ธฐ
OPCPackage pkg = OPCPackage.open(inputStream);
XSSFReader xssfReader = new XSSFReader(pkg);
ReadOnlySharedStringsTable data = new ReadOnlySharedStringsTable(pkg);
StylesTable styles = xssfReader.getStylesTable();
InputStream sheetStream = xssfReader.getSheetsData().next();
//InputStream sheetStream = xssfReader.getSheet("rId1"); // ์ฒซ๋ฒ์งธ ์ํธ๋ง ๊บผ๋ด๊ธฐ
// <ํน์ ์ํธ๋ง ๊บผ๋ด๊ณ ์ถ์๊ฒฝ์ฐ>
// InputStream sheetStream = xssfReader.getSheet("rId1"); // ์ฒซ๋ฒ์งธ ์ํธ๋ง ๊บผ๋ด๊ธฐ
// rId1 - 1๋ฒ์งธ์ํธ rId2 - 2๋ฒ์งธ์ํธ๋ฅผ ์๋ฏธ
InputSource sheetSource = new InputSource(sheetStream);
ContentHandler handler = new XSSFSheetXMLHandler(styles, data, sheetHandler, false);
XMLReader sheetParser = SAXHelper.newXMLReader();
sheetParser.setContentHandler(handler);
sheetParser.parse(sheetSource);
sheetStream.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
return sheetHandler;
}
// ๋ฐฉ์ 2
public static SheetHandler readExcel2(MultipartFile file) {
SheetHandler sheetHandler = new SheetHandler();
try {
// ์
๋ก๋๋ ํ์ผ์ InputStream ์ป๊ธฐ
InputStream inputStream = file.getInputStream();
// InputStream์ผ๋ก๋ถํฐ OPCPackage ์ด๊ธฐ
OPCPackage pkg = OPCPackage.open(inputStream);
// XSSFReader๋ฅผ ์ฌ์ฉํ์ฌ OPCPackage์์ ๋ฐ์ดํฐ๋ฅผ ์ฝ๊ธฐ
XSSFReader xssfReader = new XSSFReader(pkg);
ReadOnlySharedStringsTable data = new ReadOnlySharedStringsTable(pkg);
StylesTable styles = xssfReader.getStylesTable();
// ์ํธ๋ฅผ ๋ฐ๋ณตํ๋ฉด์ ์ฒ๋ฆฌ
XSSFReader.SheetIterator sheetIterator = (XSSFReader.SheetIterator) xssfReader.getSheetsData();
InputStream sheetStream = null;
while (sheetIterator.hasNext()) {
InputStream currentSheetStream = sheetIterator.next();
// sheetName์ผ๋ก ๋ถ๋ฅํ๊ธฐ
String sheetName = sheetIterator.getSheetName();
// ํน์ ์ํธ๋ค์ ๊ฑด๋๋ฐ๊ธฐ
if ("์ฃผ์์ฌํญ".equals(sheetName)) {
sheetStream = currentSheetStream;
System.out.println("sheetName :: " + sheetName);
}
}
// ์ฒ๋ฆฌํ ์ํธ๊ฐ ์์ผ๋ฉด ์์ธ ๋ฐ์
if (sheetStream == null) {
throw new IllegalArgumentException("Sheet not found");
}
// ์ํธ์ InputSource ์์ฑ
InputSource sheetSource = new InputSource(sheetStream);
// XSSFSheetXMLHandler๋ฅผ ์ฌ์ฉํ์ฌ ์ํธ์ ๋ด์ฉ์ ์ฒ๋ฆฌํ ContentHandler ์์ฑ
ContentHandler handler = new XSSFSheetXMLHandler(styles, data, sheetHandler, false);
// SAX ํ์๋ฅผ ์์ฑํ๊ณ ContentHandler ์ค์ ํ์ฌ ์ํธ์ ๋ด์ฉ ํ์ฑ
XMLReader sheetParser = SAXHelper.newXMLReader();
sheetParser.setContentHandler(handler);
sheetParser.parse(sheetSource);
sheetStream.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
return sheetHandler;
}
}
Apache POI Streaming API doesn't recognize Excel (xlsx) content
I have a class which ingests .xlsx-files. I took it from this example and modified it for my needs: https://svn.apache.org/repos/asf/poi/trunk/src/examples/src/org/apache/poi/xssf/eventusermodel/XL...
stackoverflow.com
SheetHandler.java
package egovframework.com.cmm.web;
import java.util.ArrayList;
import java.util.List;
import org.apache.poi.hssf.util.CellReference;
import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler.SheetContentsHandler;
import org.apache.poi.xssf.usermodel.XSSFComment;
public class SheetHandler implements SheetContentsHandler {
private List<List<String>> rows = new ArrayList<>();
private List<String> row = new ArrayList<>();
private List<String> header = new ArrayList<>();
private int currentCol = -1;
private int currRowNum = 0;
public List<String> getHeader() {
return header;
}
public List<List<String>> getRows() {
return rows;
}
public void startRow(int rowNum) {
this.currentCol = -1;
this.currRowNum = rowNum;
}
public void endRow(int rowNum) {
if(rowNum ==0) {
header = new ArrayList(row);
} else {
if(row.size() < header.size()) {
for (int i = row.size(); i < header.size(); i++) {
row.add("");
}
}
rows.add(new ArrayList(row));
}
row.clear();
}
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);
}
public void headerFooter(String text, boolean isHeader, String tagName) {
}
}
ํ ์คํธ ๊ฒฐ๊ณผ
107MB ํฌ๊ธฐ์ .xlsx ํ์ผ ํ ์คํธ
XSSFWorkbook ์ฌ์ฉ | OutOfMemoryError ๋ฐ์ |
XSSFWorkbook + OPCPackage ์ฌ์ฉ | OutOfMemoryError ๋ฐ์ |
SAX ์ฒซ๋ฒ์งธ ์ํธ๋ฏผ ์ฌ์ฉ | Memory Before Processing (bytes): 377,279,896 Memory After Processing (bytes): 1,312,857,664 Memory Used (bytes): 935,577,768 |
SAX ๋๋ฒ์งธ ์ํธ๋ฏผ ์ฌ์ฉ | Memory Before Processing (bytes): 374,138,704 Memory After Processing (bytes): 1,156,792,120 Memory Used (bytes): 782,653,416 |
SAX ์ ์ฒด ์ํธ ์ฌ์ฉ | Memory Before Processing (bytes): 376,451,232 Memory After Processing (bytes): 1,683,191,008 Memory Used (bytes): 1,306,739,776 |
213MB ํฌ๊ธฐ์ .xlsx ํ์ผ ํ ์คํธ
XSSFWorkbook ์ฌ์ฉ | OutOfMemoryError ๋ฐ์ |
XSSFWorkbook + OPCPackage ์ฌ์ฉ | OutOfMemoryError ๋ฐ์ |
SAX ์ธ๋ฒ์งธ ์ํธ๋ฏผ ์ฌ์ฉ | Memory Before Processing (bytes): 374,325,384 Memory After Processing (bytes): 2,266,669,232 Memory Used (bytes): 1,892,343,848 |
SAX ์ ์ฒด ์ํธ ์ฌ์ฉ | Memory Before Processing (bytes): 235,024,768 Memory After Processing (bytes): 2,764,111,600 Memory Used (bytes): 2,529,086,832 |
XSSFReader (POI API Documentation)
java.io.InputStream getWorkbookData() Returns an InputStream to read the contents of the main Workbook, which contains key overall data for the file, including sheet definitions.
poi.apache.org
Java ๋์ฉ๋ ์์ ์ ๋ก๋
์น ์๋น์ค๋ฅผ ํตํด ์ฌ์ฉ์๋ก๋ถํฐ ๋ฐ์ดํฐ๋ฅผ ์ ๋ ฅ ๋ฐ๋ ์ ์ฅ์์, ์ค๋ณต๋ ์ ํ์ ๋ฐ์ดํฐ๋ฅผ ๋๋์ผ๋ก ์ ๋ ฅ ๋ฐ๊ธฐ...
blog.naver.com