POI실적
J2EE 웹 애플리케이션에서 POI를 사용하여 워크북을 생성하고 있습니다.그러나 POI는 25K 행(각각 약 15개의 열)이 있는 워크북을 만드는 데 약 3분이 걸린다는 것을 알게 되었습니다.POI 성능 문제입니까, 아니면 그렇게 많은 시간을 소요하는 것이 정당합니까?더 나은 성능으로 알려진 다른 API가 있습니까?
표준 API 대신 '스트리밍' POI API를 사용하면 POI로 대용량 파일을 작성하는 성능이 크게 저하될 수 있습니다.실제로 기본 POI는 마지막에 모든 데이터를 한 번에 쓰기 전에 모든 데이터를 메모리에 저장합니다.대용량 파일의 경우 메모리 설치 공간이 터무니없이 클 수 있습니다.스트리밍 API를 사용하는 대신 메모리가 사용되고 데이터가 디스크에 점진적으로 기록되는 방식을 제어할 수 있습니다.
스트리밍 워크북을 만들려면 다음과 같은 방법을 사용합니다.
SXSSFWorkbook book = new SXSSFWorkbook();
book.setCompressTempFiles(true);
SXSSFSheet sheet = (SXSSFSheet) book.createSheet();
sheet.setRandomAccessWindowSize(100);// keep 100 rows in memory, exceeding rows will be flushed to disk
// ...
POI가 이러한 파일을 생성하는 데 그렇게 많은 시간이 걸리는 것을 보면 매우 놀랄 것입니다.저는 방금 약 18s에서 3만 행 x 10개의 셀이 있는 시트를 생성했습니다(형식 지정 없음, 공정하게 말하자면).원인은 다음 중 하나일 수 있습니다.
- 여기에 설명된 대로 POI 로깅이 설정되어 있을 수 있습니다.
- 스왑 메모리에서 실행 중입니다.
- VM 사용 가능한 힙이 매우 낮을 수 있습니다.
만약 다른 답들이 모두 해결되지 않는다면, 앤디 칸의 Jexcel이 더 나아질지 알아보세요.저는 자바에서 엑셀을 다루는 것이 POI보다 훨씬 우수하다는 것을 알았습니다.
우리는 또한 우리의 웹 앱에서 POI를 사용하고 있으며, 우리가 생성한 문서가 당신의 것보다 훨씬 적지만, 성능에는 아무런 문제가 없습니다.저는 우선 POI가 진짜 문제인지 확인하겠습니다.J2EE 오버헤드(단위 테스트) 없이 해당 문서를 생성하고 성능을 측정합니다.또한 J2EE 서버의 로드 및 메모리 사용량을 모니터링하여 문제가 일부 차선의 시스템 설정에서 발생하는지 확인할 수 있습니다.
Apache POI와 Jexcel 라이브러리를 비교했습니다.JExcel은 Apache POI보다 최대 4배 빠른 것으로 보이지만 메모리 소비는 거의 동일한 것으로 보입니다.
@Test
public void createJExcelWorkbook() throws Exception {
WritableWorkbook workbook = Workbook.createWorkbook(new File("jexcel_workbook.xls"));
WritableSheet sheet = workbook.createSheet("sheet", 0);
for ( int i=0; i < 65535; i++) {
for ( int j=0; j < 10; j++) {
Label label = new Label(j, i, "some text " + i + " " + j);
sheet.addCell(label);
}
}
workbook.write();
workbook.close();
}
@Test
public void createPoiWorkbook() throws Exception {
Workbook wb = new HSSFWorkbook();
Sheet sheet = wb.createSheet("sheet");
for ( int i=0; i < 65535; i++) {
Row row = sheet.createRow(i);
for ( int j=0; j < 10; j++) {
Cell cell = row.createCell(j);
cell.setCellValue("some text " + i + " " + j);
}
}
FileOutputStream fileOut = new FileOutputStream("poi_workbook.xls");
wb.write(fileOut);
fileOut.close();
}
저는 Jexcel 버전 2.6.12와 Apache POI 버전 3.7로 테스트했습니다.보다 정확한 숫자를 얻으려면 최신 라이브러리 버전을 직접 다운로드하고 위의 간단한 테스트를 실행해야 합니다.
<dependency org="org.apache.poi" name="poi" rev="3.7"/>
<dependency org="net.sourceforge.jexcelapi" name="jxl" rev="2.6.12"/>
참고: Apache POI에는 시트당 65535행의 제한이 있습니다.
기본적으로 POI는 대용량 XLSX 문서를 위해 저장해야 하는 많은 항목인 XmlBeans를 사용하여 문서를 메모리에 저장합니다.
이 파일은 사용자가 스트리밍할 때만 XLSX 문서(zip 파일)가 됩니다.
큰 문서의 경우 메모리 호그이며 속도가 느릴 수 있습니다.
SXSSF 클래스는 데이터 파일이 생성될 때 디스크에 데이터 파일을 쓰고 XLSX가 출력될 때 파일의 나머지 부분과 병합하여 이러한 오버헤드를 방지합니다.이것은 큰 문제집에 비해 훨씬 빠르지만 한계가 있습니다.
훨씬 덜 유연하지만 훨씬 더 효율적인 또 다른 접근법이 있습니다.이 접근 방식은 XLSX의 대부분의 파일을 거의 고정된 것으로 간주하고 생성 시 전체 로트를 스트리밍하는 것입니다.이는 고유한 제한이 있지만(모든 yiur 포맷을 미리 알고 있어야 함) 빠르고 메모리 효율적입니다.제가 이 접근 방식을 구현한 곳은 https://github.com/Yaytay/vertx-xlsx-writer, 입니다. 하지만 꽤 간단합니다.
Excel에서 사용하는 메모리 내 모델은 XLSX 형식과 거의 공통점이 없으며 관련 정보를 검색하여 각 파일을 한 번에 빌드한다고 가정합니다.필요한 파일 형식의 비트만 선택하면 동일한 작업을 수행할 수 있습니다.
언급URL : https://stackoverflow.com/questions/2498536/poi-performance
'programing' 카테고리의 다른 글
| 윈도우에서 커피스크립트? (0) | 2023.05.16 |
|---|---|
| 명령줄에서 데이터베이스 만들기 (0) | 2023.05.16 |
| LINQ 쿼리에서 ToList() 또는 ToArray()를 호출하는 것이 더 나을까요? (0) | 2023.05.16 |
| 프로세스가 lxc/Docker 내부에서 실행되는지 확인하는 방법은 무엇입니까? (0) | 2023.05.11 |
| HTML.ActionLink 메서드 (0) | 2023.05.11 |