대용량 Excel 파일 쓰기(50w+ 지원) (2)
12003 단어 Java 기반
대용량 Excel 파일 쓰기(50w+ 지원)
1 온라인 메모리 넘침 문제 프레젠테이션
환경 준비
jvm 실행 매개 변수 설정은 다음과 같습니다.
-Xms100M -Xmx100M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=d://dump.hprof
예제 코드/**
* excel
*
* @author Leon
* @date 2020-05-06 11:23
*/
public class WriteExcelDemo
{
public static void main(String[] args) throws Exception
{
XSSFWorkbook wb = new XSSFWorkbook();
XSSFSheet sheet = wb.createSheet("sheet-test");
// 50
for (int i = 0; i < 500000; i++)
{
XSSFRow curRow = sheet.createRow(i);
XSSFCell cell = curRow.createCell(0);
cell.setCellValue(LocalDate.now().toString());
}
FileOutputStream fos = new FileOutputStream("d:\\test111.xlsx");
wb.write(fos);
fos.close();
}
}
실행 결과
java.lang.OutOfMemoryError: GC overhead limit exceeded
Dumping heap to d://dump.hprof ...
Heap dump file created [163701970 bytes in 0.973 secs]
Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
at org.apache.xmlbeans.impl.store.Xobj.ensureParent(Xobj.java:614)
at org.apache.xmlbeans.impl.store.Xobj.getNormal(Xobj.java:661)
at org.apache.xmlbeans.impl.store.Cur.getNormal(Cur.java:2464)
at org.apache.xmlbeans.impl.store.Cur.skip(Cur.java:1269)
at org.apache.xmlbeans.impl.store.Cur.moveNode(Cur.java:1840)
at org.apache.xmlbeans.impl.store.Cur.createHelper(Cur.java:287)
at org.apache.xmlbeans.impl.store.Cur.createElement(Cur.java:231)
at org.apache.xmlbeans.impl.store.Cur.createElement(Cur.java:226)
at org.apache.xmlbeans.impl.store.Xobj.insertElement(Xobj.java:2116)
at org.apache.xmlbeans.impl.store.Xobj.add_element_user(Xobj.java:2197)
at org.openxmlformats.schemas.spreadsheetml.x2006.main.impl.CTRowImpl.addNewC(Unknown Source)
at org.apache.poi.xssf.usermodel.XSSFRow.createCell(XSSFRow.java:220)
at org.apache.poi.xssf.usermodel.XSSFRow.createCell(XSSFRow.java:198)
at com.concurrent.excel.WriteExcelDemo.main(WriteExcelDemo.java:35)
우리는 메모리가 넘치는 것을 발견했다.
2 작은 메모리로 초대형 excel 데이터 쓰기
지난 소절에서 우리는 OOM 현상과 원인을 설명했고 이런 상황에 대해 POI 정부도 해결 방안을 제시했다.바로
SXSSF
.POI는 SXSSF의 방식으로 매우 큰 xlsx 파일을 유동적으로 만들 수 있습니다. SXSSF는 윈도우의 개념을 사용합니다. 데이터 줄이 윈도우의 범위를 초과하면 내용을 수정할 수 없습니다.
이 창의 크기는 구조 함수
new SXSSFWorkbook(int windowSize)
나 sheet SXSSFSheet#setRandomAccessWindowSize(int windowSize)
에서 설정할 수 있으며, 기본값은 SXSSFWorkbook.DEFAULT_WINDOW_SIZE(100)
입니다.또한 SXSSF는 임시 파일을 만들 수 있습니다. 이것은finally에서 디스플레이를 사용하여 디스포지션을 호출하여 제거해야 합니다. 또한 임시 파일도 일정한 하드디스크를 사용합니다.
wb.setCompressTempFiles(true)
워크북의 임시 파일을 설정하여 압축을 사용하여 하드디스크의 사용을 줄일 수 있습니다.예는 다음과 같다.
예제 코드
이 코드는 생산 환경에 직접 사용할 수 있습니다.
/**
* excel
*
* @author Leon
* @date 2020-05-06 11:23
*/
public class SxssfWriteExcelDemo
{
public static void main(String[] args) throws Exception
{
// jvm : -Xms100M -Xmx100M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=d://dump.hprof
SXSSFWorkbook wb = new SXSSFWorkbook();
try
{
Sheet sheet = wb.createSheet();
// 100
for (int i = 0; i < 1000000; i++)
{
Row curRow = sheet.createRow(i);
Cell cell = curRow.createCell(0);
cell.setCellValue(LocalDate.now().toString() + UUID.randomUUID().toString() + new Random().nextInt());
}
FileOutputStream fos = new FileOutputStream("d:\\test111.xlsx");
wb.write(fos);
fos.close();
}
finally
{
//
if( wb != null)
{
wb.dispose();
}
}
System.out.println("ok");
}
}
실행 결과
100w개의 데이터를 성공적으로 썼고 어떠한 오류도 보고하지 않았습니다.
3 매듭
SXSSF는 큰 파일을 쓰는 문제를 해결할 수 있지만 파일의 원래 내용을 수정할 수 없고 원본 파일을 읽을 수도 없습니다.
필요한 경우 이전에 읽은 큰 파일과 결합하여 읽은 내용을 SXSSF를 통해 새 파일에 작성하여 유사한 수정 작업을 수행할 수 있습니다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
FTP의 액티브 모드 및 패시브 모드로그인에 성공한 후list 목록이나 데이터를 읽을 때 클라이언트는 랜덤으로 하나의 포트(1024 이상)를 개방하고 포트를 FTP 서버에 보내서 서버 클라이언트에게 주동 모드를 사용하고 개방하라고 알려준다 FTP 서버...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.