2017-05-17 1 views
1

Apache Poi와 함께 작업 중입니다. XSSFWorkbooksxlsx 파일을 조작합니다. 내 프로그램은 작은 엑셀 파일 (60 000 행)에서 잘 작동합니다. 큰 파일 (700,000 행)에서 코드를 테스트하기 시작했을 때 나는 메모리 문제가있었습니다. 16GB RAM이 장착 된 컴퓨터에서 코드를 테스트했는데 작동하지 않습니다.Java 힙 공간 오류, Java에서 큰 xlsx 파일을 처리 할 수 ​​없습니다.

이 문제에 도움이 되셨습니까? SAX 파서에 대해 읽었지 만 코드를 수정하고 싶지는 않으며 사용하기 쉽지 않습니다. xssf 세포, 행을 얻는 간단한 방법이 있습니다. 예 :

내 코드를 그대로 유지하고 메모리 문제를 해결할 수있는 방법이 있습니까? 또는 SAX 파서를 제외한 다른 솔루션? 감사합니다. 감사합니다.

+4

증가 힙 크기를보십시오 : 문제 : http://stackoverflow.com/questions/1565388/increase-heap-size-in-java –

+0

SAX 하나 개의 좋은 솔루션이며 당신이 돈 때문에 CSV 형식은 좋은 대안이 될 수 있습니다. CSV 형식은 Excel에서 열 수 있으며 좋은 이유는 메모리에 한꺼번에 읽는 대신 스트리밍 할 수있는 형식을 사용하는 것이 좋습니다. content-type을 application/vnd.ms-excel 및 extention type ".xls"로 설정하십시오. –

답변

3

경험상 SAX는 메모리 성능에 많은 도움이되었습니다. 4GB 이상에서 약 300MB로갔습니다.

일부 유용한 링크 및 기타 팁 :

파일 크기/메모리 사용

https://poi.apache.org/spreadsheet/limitations.html에서

Excel 파일 형식으로 몇 가지 고유 한 한계가있다. 이들은 SpreadsheetVersion 클래스에 정의 된 입니다. 충분한 수의 메인 메모리가 있다면,이 한계까지 파일을 처리 할 수 ​​있어야합니다. 기본 POI 클래스를 사용하는 거대한 파일의 경우 매우 많은 양의 메모리가 필요할 수 있습니다 ( ).

가 필요한 경우 메인 메모리의 한계를 극복 할 수있는 방법이 있습니다 : 매우 큰 파일을 작성 를 들어, 당신이 뭘 할 수 있는지에 대한 특정 제한 사항 (파일에서 데이터의 스트리밍 쓰기를 수행 할 수 있습니다 SXSSFWorkbook있다 파일의 일부만 메모리에 저장되므로). 매우 큰 파일을 보려면 스트리밍 방식으로 파일을 읽을 수있는 방법을 보여주는 샘플 XLSX2CSV를 확인하십시오. (다시 한 번 파일에서 읽을 수있는 정보에 대해서는 을 입력하십시오.) 필요한 경우 대부분).

또한

https://poi.apache.org/faq.html#faq-N10165

  1. 내가 POI가 너무 많은 메모리를 사용하고있는 것! 내가 무엇을 할 수 있을지? 이 문제는 상당히 많이 발생하지만 종종 이유는 처음에 이 생각할 수있는 것이 아닙니다. 따라서 우선 확인해야 할 것은 무엇입니까? 문제의 소스는 입니까? 너의 파일? 당신의 코드? 당신의 환경? 아니면 아파치 POI? 당신이 여기 있다면

은 (, 당신은 아마 아파치 POI 생각합니다. 그러나, 그것은 종종 이 아니다! 온건 한 노트북을, 괜찮은하지만 과도하지 힙 크기, 와 서 처음부터 할 수 일반적으로 컬럼과 100,000 개의 행을 가진 파일을 읽거나 쓰십시오 (예 : JVM 시작 시간 포함). 몇 가지 기본적인 성능 검사를 수행하는 데 사용할 수있는 몇 가지 프로그램과 몇 가지 예제 프로그램과

아파치 POI 제공됩니다. 테스트 파일 세대를 들어, 사용하는 클래스는 예 패키지에, SSPerformanceTest (viewvc). 쓰기 유형 (HSSF, XSSF 또는 SXSSF)의 인수와 함께 실행 SSPerformanceTest, 숫자 행의 열 수 및 파일을 저장해야하는 경우. HSSF 및 SXSSF의 50,000 행 및 50 개의 열을 3 초 미만으로 실행하고 XSSF를 10 초 미만 (그리고 이상적으로 모두 3 미만)으로 실행하면 환경에 문제가있는 것입니다. .

다음 예제 프로그램 ToCSV (viewvc)를 사용하여 HSSF 또는 XSSF로 파일을 읽으십시오. 관련 .XLSX에 대한 구문 분석 SAX 를 사용 (viewvc) XLSX2CSV입니다. 문제 파일과 같은 크기의 SSPerformanceTest에 의해 생성 된 간단한 모두에 대해이 작업을 실행합니다. 이 느린 경우, 파일입니다 가 처리되는 방법에 아파치 POI의 문제가있을 수 (POI는 항상 옳다 모든 파일에 하지 않을 수있는 몇 가지 가정을합니다). 이 테스트가 빠르면 어떤 성능 문제가 코드에 있습니다! http://poi.apache.org/spreadsheet/quick-guide.html#FileInputStream

When opening a workbook, either a .xls HSSFWorkbook, or a .xlsx XSSFWorkbook, the Workbook can be loaded from either a File or an InputStream. Using a File object allows for lower memory consumption, while an InputStream requires more memory as it has to buffer the whole file. 

If using WorkbookFactory, it's very easy to use one or the other: 

    // Use a file 
    Workbook wb = WorkbookFactory.create(new File("MyExcel.xls")); 

    // Use an InputStream, needs more memory 
    Workbook wb = WorkbookFactory.create(new FileInputStream("MyExcel.xlsx")); 

이 NPOIFSFileSystem 또는 OPCPackage 통과 일반적으로 직접 HSSFWorkbook 또는 XSSFWorkbook을, 당신이해야 사용하는 경우에는, InputStream는, 모든 권한을 가지고 대

그리고

파일 라이프 사이클 (파일을 닫을 때 포함)) 수행 :

// HSSFWorkbook, File 
    NPOIFSFileSystem fs = new NPOIFSFileSystem(new File("file.xls")); 
    HSSFWorkbook wb = new HSSFWorkbook(fs.getRoot(), true); 
    .... 
    fs.close(); 

    // HSSFWorkbook, InputStream, needs more memory 
    NPOIFSFileSystem fs = new NPOIFSFileSystem(myInputStream); 
    HSSFWorkbook wb = new HSSFWorkbook(fs.getRoot(), true); 

    // XSSFWorkbook, File 
    OPCPackage pkg = OPCPackage.open(new File("file.xlsx")); 
    XSSFWorkbook wb = new XSSFWorkbook(pkg); 
    .... 
    pkg.close(); 

    // XSSFWorkbook, InputStream, needs more memory 
    OPCPackage pkg = OPCPackage.open(myInputStream); 
    XSSFWorkbook wb = new XSSFWorkbook(pkg); 
    .... 
    pkg.close(); 
+0

매우 친절하고 답변을 설명합니다. 시간을내어 주셔서 감사 드리며, +1을 작성해주십시오. 심지어 향상시킬 수있는 응용 프로그램을 배웠습니다. – Nico

관련 문제