2012-07-05 40 views
10

Tôi đang sử dụng XSSF của apache-POI để đọc tệp XLSX. Tôi đã gặp lỗi java.lang.OutOfMemoryError: Java heap space. Sau đó, tăng kích thước heap bằng cách sử dụng -Xmx1024m cho lớp java vẫn cùng một lỗi lặp lại.Cách đọc tệp XLSX có kích thước> 40MB

Code:

String filename = "D:\\filename.xlsx"; 
FileInputStream fis = null; 
try { 
    fis = new FileInputStream(filename); 
    XSSFWorkbook workbook = new XSSFWorkbook(fis); 

Trong đoạn mã trên, việc thực hiện dừng lại ở XSSFWorkbook và ném các lỗi cụ thể. Ai đó có thể đề xuất cách tiếp cận tốt hơn để đọc các tệp XLSX lớn.

+0

Bạn chạy nó từ IDE như nhật thực? bạn đã đặt các tùy chọn bộ nhớ như thế nào? Tôi nghĩ rằng cài đặt của bạn có thể không thực hiện đúng cách. –

+0

vâng, tôi đang sử dụng IDE nhật thực và thực hiện các thay đổi sau cho nó ... 1) Trong eclipse.ini đã chỉnh sửa -Xmx256M thành -Xmx-1024M 2) Trong cửa sổ IDE-> prefrences-> JRE đã cài đặt-> được thêm vào - Xms256M -Xmx1024M trong các đối số VM mặc định. Tôi nghĩ rằng nó có thể đã phản ánh trong nhật thực IDE – Avinash

Trả lời

14

POI cho phép bạn đọc các tệp excel theo cách trực tuyến. API là khá nhiều một wrapper xung quanh SAX. Hãy chắc chắn rằng bạn mở gói OPC theo cách chính xác, sử dụng hàm tạo có một String. Nếu không, bạn có thể hết bộ nhớ ngay lập tức.

OPCPackage pkg = OPCPackage.open(file.getPath()); 
XSSFReader reader = new XSSFReader(pkg); 

Bây giờ, trình đọc sẽ cho phép bạn nhận InputStreams cho các phần khác nhau. Nếu bạn muốn tự phân tích cú pháp XML (sử dụng SAX hoặc StAX), bạn có thể sử dụng chúng. Nhưng nó đòi hỏi rất quen thuộc với định dạng.

Một tùy chọn dễ dàng hơn là sử dụng XSSFSheetXMLHandler. Dưới đây là một ví dụ mà đọc sheet đầu tiên:

StylesTable styles = reader.getStylesTable(); 
ReadOnlySharedStringsTable sharedStrings = new ReadOnlySharedStringsTable(pkg); 
ContentHandler handler = new XSSFSheetXMLHandler(styles, sharedStrings, mySheetContentsHandler, true); 

XMLReader parser = XMLReaderFactory.createXMLReader(); 
parser.setContentHandler(handler); 
parser.parse(new InputSource(reader.getSheetsData().next())); 

đâu mySheetsContentHandler nên thực hiện của riêng bạn XSSFSheetXMLHandler.SheetContentsHandler. Lớp này sẽ được cho ăn các hàng và các ô. Tuy nhiên, hãy lưu ý rằng điều này có thể tốn nhiều bộ nhớ nếu bảng chuỗi chia sẻ của bạn rất lớn (điều này xảy ra nếu bạn không có bất kỳ chuỗi trùng lặp nào trong các trang tính lớn). Nếu bộ nhớ vẫn còn là một vấn đề, tôi khuyên bạn nên sử dụng các luồng XML thô (cũng được cung cấp bởi XSSFReader).

+0

Câu trả lời tuyệt vời, cảm ơn rất nhiều! –

+0

Có thể bạn có thể giúp tôi giải quyết vấn đề này: http://stackoverflow.com/questions/31939669/how-to-interrupt-poi-streaming-reader-after-reading-the-first-line –

Các vấn đề liên quan