Tuve el mismo problema con 800,000 celdas y 3M caracteres donde XSSF asigna 1GB de montón.
Utilicé Python con openpyxl
y numpy
para leer el archivo xlsx (desde código Java) y primero convertirlo a texto normal. Luego cargué el archivo de texto en java. Puede parecer tener grandes gastos generales, pero de hecho es rápido.
El script en Python parece
import openpyxl as px
import numpy as np
# xlsx file is given through command line foo.xlsx
fname = sys.argv[1]
W = px.load_workbook(fname, read_only = True)
p = W.get_sheet_by_name(name = 'Sheet1')
a=[]
# number of rows and columns
m = p.max_row
n = p.max_column
for row in p.iter_rows():
for k in row:
a.append(k.value)
# convert list a to matrix (for example maxRows*maxColumns)
aa= np.resize(a, [m, n])
# output file is also given in the command line foo.txt
oname = sys.argv[2]
print (oname)
file = open(oname,"w")
mm = m-1
for i in range(mm):
for j in range(n):
file.write("%s " %aa[i,j] )
file.write ("\n")
# to prevent extra newline in the text file
for j in range(n):
file.write("%s " %aa[m-1,j])
file.close()
Luego, en mi código java, escribí
try {
// `pwd`\python_script foo.xlsx foo.txt
String pythonScript = System.getProperty("user.dir") + "\\exread.py ";
String cmdline = "python " + pythonScript +
workingDirectoryPath + "\\" + fullFileName + " " +
workingDirectoryPath + "\\" + shortFileName + ".txt";
Process p = Runtime.getRuntime().exec(cmdline);
int exitCode = p.waitFor();
if (exitCode != 0) {
throw new IOException("Python command exited with " + exitCode);
}
} catch (IOException e) {
System.out.println(e.getMessage());
} catch (InterruptedException e) {
ReadInfo.append(e.getMessage());
}
Después de eso, obtendrá foo.txt que es similar a foo.xlsx, pero en formato de texto.
¿Dónde se está ejecutando el código? Dentro de la aplicación/servidor web o independiente? – JSS
Lo estoy ejecutando dentro de Tomcat 6.0 – miah
¿Cuál es la asignación de memoria predeterminada a Tomcat en el inicio? – JSS