2012-07-05 34 views
10

Estoy usando XSSF de apache-POI para leer el archivo XLSX. Me estaba dando un error java.lang.OutOfMemoryError: Java heap space. Más tarde, aumentó el tamaño del almacenamiento dinámico utilizando -Xmx1024m para la clase Java, pero se repite el mismo error.Cómo leer el archivo XLSX de tamaño> 40MB

Código:

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

En el segmento de código anterior, la ejecución se detiene en XSSFWorkbook y lanza el error especificado. ¿Alguien puede sugerir un mejor enfoque para leer archivos XLSX grandes?

+0

¿Lo está ejecutando desde IDE como eclipse? ¿Cómo establecieron las opciones de memoria? Creo que su configuración puede no efectuarse correctamente. –

+0

sí, estoy usando eclipse IDE y realicé los siguientes cambios ... 1) En eclipse.ini edité el -Xmx256M a -Xmx-1024M 2) En ventana IDE-> Preferencias-> JRE-> Instalado -> agregado - Xms256M -Xmx1024M en argumentos VM por defecto. Creo que se pudo haber reflejado en el eclipse IDE – Avinash

Respuesta

14

POI le permite leer archivos de Excel de forma continua. La API es una especie de envoltorio alrededor de SAX. Asegúrese de abrir el paquete OPC de la manera correcta, utilizando el constructor que toma una Cadena. De lo contrario, podría quedarse sin memoria inmediatamente.

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

Ahora, lector le permitirá obtener InputStreams para las diferentes partes. Si quiere hacer el análisis XML usted mismo (usando SAX o StAX), puede usarlos. Pero requiere estar muy familiarizado con el formato.

Una opción más fácil es usar XSSFSheetXMLHandler. Aquí hay un ejemplo que lee la primera hoja:

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())); 

Dónde mySheetsContentHandler debe ser su propia implementación de XSSFSheetXMLHandler.SheetContentsHandler. Esta clase se alimentará con filas y celdas.

Sin embargo, tenga en cuenta que esto puede consumir una cantidad moderada de memoria si la tabla de cadenas compartidas es enorme (lo que sucede si no tiene cadenas duplicadas en las hojas grandes). Si la memoria sigue siendo un problema, recomiendo usar las secuencias XML sin procesar (también proporcionadas por XSSFReader).

+0

¡Respuesta increíble, muchas gracias! –

+0

Quizás podría ayudarme a resolver este problema: http://stackoverflow.com/questions/31939669/how-to-interrupt-poverty-reader-after-reading-the-first-line –