- 100MB 초과로 인한 엑셀 파싱 실패
org.apache.poi.util.RecordFormatException: Tried to read data but the maximum length for this record type is 100,000,000.
If the file is not corrupt and not large, please open an issue on bugzilla to request
increasing the maximum allowable size for this record type.
You can set a higher override value with IOUtils.setByteArrayMaxOverride()
- 에러 유형
- org.apache.poi.util.RecordFormatException
- 발생 원인
- excel 파일을 읽는 도중, 허용된 최대 크기(100MB)를 초과한 데이터를 포함한 레코드를 읽으려고 함
- 제한 사항
- Apache POI는 기본적으로 1개의 레코드에 대해 100MB(100,000,000 바이트)까지만 읽도록 설정되어 있음.
레코드란??
내부적으로는 파일을 구성하는 여러 XML 혹은 바이너리 블록 단위
ex) sheet1 , styles, drawing
- 실제 압축 크기와 압축 해제 후 크기 확인
- xl/worksheets/sheet1.xml
- 압축 크기 : 22.05 MB
- 압축 해제 크기 : 246.73 MB
public <T> List<T> parseExcelToObject(MultipartFile file, Class<T> clazz) throws IOException {
// MultipartFile을 임시 파일로 저장
File tempFile = File.createTempFile("uploaded", ".xlsx");
file.transferTo(tempFile);
try (ZipFile zipFile = new ZipFile(tempFile)) {
Enumeration<? extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
System.out.println("Entry: " + entry.getName()
+ ", Compressed Size: " + entry.getCompressedSize()
+ ", Uncompressed Size: " + entry.getSize());
}
} finally {
// 작업 끝나면 임시 파일 삭제
tempFile.delete();
}
Workbook workbook = WorkbookFactory.create(file.getInputStream());
Sheet sheet = workbook.getSheetAt(0);
parseHeader(sheet, clazz);
return parseBody(sheet, clazz);
}
Entry: xl/drawings/drawing1.xml, Compressed Size: 261, Uncompressed Size: 775
Entry: xl/worksheets/sheet1.xml, Compressed Size: 23125563, Uncompressed Size: 258712875
Entry: xl/worksheets/_rels/sheet1.xml.rels, Compressed Size: 179, Uncompressed Size: 298
Entry: xl/theme/theme1.xml, Compressed Size: 808, Uncompressed Size: 3757
Entry: xl/sharedStrings.xml, Compressed Size: 237, Uncompressed Size: 352
Entry: xl/styles.xml, Compressed Size: 575, Uncompressed Size: 2192
Entry: xl/workbook.xml, Compressed Size: 339, Uncompressed Size: 807
Entry: xl/_rels/workbook.xml.rels, Compressed Size: 234, Uncompressed Size: 697
Entry: _rels/.rels, Compressed Size: 178, Uncompressed Size: 296
Entry: [Content_Types].xml, Compressed Size: 309, Uncompressed Size: 1049
코드 수정
public <T> List<T> parseExcelToObject(MultipartFile file, Class<T> clazz) throws IOException {
IOUtils.setByteArrayMaxOverride(300_000_000); // 레코드 크기 300MB까지 허용
Workbook workbook = WorkbookFactory.create(file.getInputStream());
Sheet sheet = workbook.getSheetAt(0);
parseHeader(sheet, clazz);
return parseBody(sheet, clazz);
}
org.apache.poi.util.RecordFormatException: Tried to read data but the maximum length for this record type is 100,000,000.
If the file is not corrupt and not large, please open an issue on bugzilla to request
increasing the maximum allowable size for this record type.
You can set a higher override value with IOUtils.setByteArrayMaxOverride()
- 발생 원인
- 압축된 .xlsx 파일 내부 항목의 압축률이 너무 높음
- 압축 전후 크기 비율이 MIN_INFLATE_RATIO (0.01)보다 낮아서 Zip Bomb으로 감지됨
xlsx 파일은 사실 ZIP 파일이다??
엑셀 크기는 22MB이지만 실제로는 더 클수있다?