POI (나는 xls와 xlsx 형식을 모두 가지고 있음)를 읽으려고하는 스프레드 시트가 있지만이 경우 xls 파일에 문제가 있습니다. 내 스프레드 시트에는 약 10,000 개의 행과 75 개의 열이 있으며 읽기에는 몇 분이 걸릴 수 있습니다 (Excel이 몇 초 안에 열림). 전체 파일을 메모리로 읽는 대신 이벤트 기반 읽기를 사용하고 있습니다. 내 코드는 다음과 같습니다. 지금은 다소 지저분하지만 실제로는 POI 예제에서 주로 복사 된 긴 switch 문입니다.Apache POI Java 스프레드 시트의 Java Excel 성능
이벤트 모델을 사용하여 POI 성능이 매우 느린 것은 일반적입니까? 이 속도를 높이기 위해 내가 할 일이 있습니까? 내 신청서에는 몇 분이 받아 들여지지 않을 것 같습니다.
POIFSFileSystem poifs = new POIFSFileSystem(fis);
InputStream din = poifs.createDocumentInputStream("Workbook");
try
{
HSSFRequest req = new HSSFRequest();
listener = new FormatTrackingHSSFListener(new HSSFListener() {
@Override
public void processRecord(Record rec)
{
thisString = null;
int sid = rec.getSid();
switch (sid)
{
case SSTRecord.sid:
strTable = (SSTRecord) rec;
break;
case LabelSSTRecord.sid:
LabelSSTRecord labelSstRec = (LabelSSTRecord) rec;
thisString = strTable.getString(labelSstRec
.getSSTIndex()).getString();
row = labelSstRec.getRow();
col = labelSstRec.getColumn();
break;
case RKRecord.sid:
RKRecord rrk = (RKRecord) rec;
thisString = "";
row = rrk.getRow();
col = rrk.getColumn();
break;
case LabelRecord.sid:
LabelRecord lrec = (LabelRecord) rec;
thisString = lrec.getValue();
row = lrec.getRow();
col = lrec.getColumn();
break;
case BlankRecord.sid:
BlankRecord blrec = (BlankRecord) rec;
thisString = "";
row = blrec.getRow();
col = blrec.getColumn();
break;
case BoolErrRecord.sid:
BoolErrRecord berec = (BoolErrRecord) rec;
row = berec.getRow();
col = berec.getColumn();
byte errVal = berec.getErrorValue();
thisString = errVal == 0 ? Boolean.toString(berec
.getBooleanValue()) : ErrorConstants
.getText(errVal);
break;
case FormulaRecord.sid:
FormulaRecord frec = (FormulaRecord) rec;
switch (frec.getCachedResultType())
{
case Cell.CELL_TYPE_NUMERIC:
double num = frec.getValue();
if (Double.isNaN(num))
{
// Formula result is a string
// This is stored in the next record
outputNextStringRecord = true;
}
else
{
thisString = formatNumericValue(frec, num);
}
break;
case Cell.CELL_TYPE_BOOLEAN:
thisString = Boolean.toString(frec
.getCachedBooleanValue());
break;
case Cell.CELL_TYPE_ERROR:
thisString = HSSFErrorConstants
.getText(frec.getCachedErrorValue());
break;
case Cell.CELL_TYPE_STRING:
outputNextStringRecord = true;
break;
}
row = frec.getRow();
col = frec.getColumn();
break;
case StringRecord.sid:
if (outputNextStringRecord)
{
// String for formula
StringRecord srec = (StringRecord) rec;
thisString = srec.getString();
outputNextStringRecord = false;
}
break;
case NumberRecord.sid:
NumberRecord numRec = (NumberRecord) rec;
row = numRec.getRow();
col = numRec.getColumn();
thisString = formatNumericValue(numRec, numRec
.getValue());
break;
case NoteRecord.sid:
NoteRecord noteRec = (NoteRecord) rec;
row = noteRec.getRow();
col = noteRec.getColumn();
thisString = "";
break;
case EOFRecord.sid:
inSheet = false;
}
if (thisString != null)
{
// do something with the cell value
}
}
});
req.addListenerForAllRecords(listener);
HSSFEventFactory factory = new HSSFEventFactory();
factory.processEvents(req, din);
느리고 xlsx가 잘 작동하는 xls입니까? 나에게 그것은 반대 다. 많은 행을 가진 파일을 작성하는 것은 xls에 대해 몇 메가 바이트의 힙을 사용하지만 xlsx에는 2GB조차 충분하지 않다. 출력에 X 행 이상이있는 경우 xls로 폴백해야합니다. – rlovtang
@rlovtang, xlsx가 더 느립니다. xls와 xlsx를 모두 처리해야하기 때문에 JExcel과 같은 것 대신 POI를 사용한다는 의미였습니다. –