Экспорт Apache POI в Excel: непоследовательное поведение в разных средах с большими наборами результатовJAVA

Программисты JAVA общаются здесь
Anonymous
Экспорт Apache POI в Excel: непоследовательное поведение в разных средах с большими наборами результатов

Сообщение Anonymous »

Я пытаюсь экспортировать большой файл Excel с помощью Apache POI (v.4.1.2) и Java (1.8). Однако я столкнулся с конкретной проблемой. У меня есть 3 среды:
  • Локальная среда
  • Тестовая среда
  • Производственная среда Environment
Как в локальной, так и в производственной среде все работает отлично, даже если запросы возвращают от 700 000 до 900 000 строк. Однако в моей тестовой среде, когда набор результатов превышает 170 000 строк, я сталкиваюсь со следующей ошибкой:
java.util.concurrent.CompletionException: java.lang.RuntimeException: java.io.IOException: This archive contains unclosed entries.
at java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:273)
at java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:280)
at java.util.concurrent.CompletableFuture.uniAccept(CompletableFuture.java:673)
at java.util.concurrent.CompletableFuture$UniAccept.tryFire(CompletableFuture.java:646)
at java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:488)
at java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1609)
at java.lang.Thread.run(Thread.java:750)
Caused by: java.lang.RuntimeException: java.io.IOException: This archive contains unclosed entries.
at it.gruppohera.sistemacomuni.exportservice.crud.service.ExcelService.convertWorkbookToByteArray(ExcelService.java:225)
at it.gruppohera.sistemacomuni.exportservice.crud.service.ContrattiAttrezzatureCrudService.lambda$generateCustomExcel$1(ContrattiAttrezzatureCrudService.java:181)
at java.util.concurrent.CompletableFuture.uniAccept(CompletableFuture.java:670)
... 4 more
Caused by: java.io.IOException: This archive contains unclosed entries.
at org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream.finish(ZipArchiveOutputStream.java:467)
at org.apache.poi.xssf.streaming.SXSSFWorkbook.injectData(SXSSFWorkbook.java:419)
at org.apache.poi.xssf.streaming.SXSSFWorkbook.write(SXSSFWorkbook.java:959)
at it.gruppohera.sistemacomuni.exportservice.crud.service.ExcelService.convertWorkbookToByteArray(ExcelService.java:222)
... 6 more

Я понимаю, что эта ошибка широко обсуждается в Интернете и идентична ошибке, описанной в этом вопросе, которая, по-видимому, и привела к этой проблеме.
Несмотря на ошибку, которую я не придумал, как исправить, кроме как с помощью другого метода извлечения (например, CSV), я не понимаю, почему поведение не одинаково во всех средах.
Параметры JVM для рабочей и тестовой среды: -XX:+UseSerialGC, тогда как в локальной среде параметры не заданы.
Вот код, используемый для создания файлов Excel:< /p>
Java
private byte[] extractInformationAndGenerateExcel(String username, List comuniList) {
logger.info("Start");

List resultList = contrattiAttrezzatureRepository.getResultsSetFromQuery(username, comuniList);
try (Workbook workbook = generateExcelService.generateExcel("EXCEL_SHEET_NAME", resultList);
ByteArrayOutputStream out = new ByteArrayOutputStream()) {
workbook.write(out);
if (workbook instanceof SXSSFWorkbook) {
((SXSSFWorkbook) workbook).dispose();
}
return out.toByteArray();
} catch (Exception e) {
throw new RuntimeException(e);
}
}

public Workbook generateExcel(String sheetName, Collection collection) throws IOException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
SXSSFWorkbook wb = new SXSSFWorkbook();
wb.setCompressTempFiles(Boolean.TRUE);
SXSSFSheet sheet = (SXSSFSheet) createSheet(sheetName, wb);
sheet.setRandomAccessWindowSize(100);
// freeze first row
sheet.createFreezePane(0, 1);

// check excel empty
if (collection.isEmpty()) {
return wb;
}

T firstElement = collection.iterator().next();
Class objectClass = firstElement.getClass();
List fields = getAllFields(objectClass);
List headerNameList = new ArrayList();
Map fieldAlloweds = new HashMap();
Map fieldType = field.getType();
fieldTypes.put(field.getName(), fieldType);
fieldAlloweds.put(field.getName(), isFieldTypeAllowed(fieldType));
String headerName = getHeaderColumnName(field);
if (headerName != null) {
headerNameList.add(headerName);
}

Method fieldGetterMethod = objectClass.getMethod(getFieldGetterMethodName(field.getName()));
fieldGetterMethods.put(field.getName(), fieldGetterMethod);
} catch (NoSuchMethodException e) {
// missing
}
}

writeHeaderLine(headerNameList, wb, sheet);

int rowCount = 1;
Iterator iter = collection.iterator();
while (iter.hasNext()) {
T element = iter.next();
Row row = sheet.createRow(rowCount);
int columnCount = 0;
for (Field field : fields) {
Method fieldGetter = fieldGetterMethods.get(field.getName());

if (fieldGetter != null && fieldAlloweds.get(field.getName())) {
Object fieldValue = fieldGetter.invoke(element);
Class fieldType = fieldTypes.get(field.getName());
if (fieldValue == null) {
fieldValue = "";
fieldType = String.class;
}
createCell(row, columnCount++, fieldValue, fieldType, null);
}
}
rowCount++;
}

return wb;
}

Может ли кто-нибудь помочь мне понять причину этого несоответствия?
это мой pom.xml

1.8
8

4.1.2




org.apache.poi
poi
${org.apache.poi.version}


org.apache.poi
poi-ooxml
${org.apache.poi.version}


org.apache.poi
poi-ooxml-schemas
${org.apache.poi.version}


org.apache.poi
poi-scratchpad
${org.apache.poi.version}



Подробнее здесь: https://stackoverflow.com/questions/788 ... nments-wit

Вернуться в «JAVA»