Код: Выделить всё
@Transactional(readOnly = true)
public byte[] extractInformationAndGenerateExcel(String username, List comuniList) {
logger.info("STARTING EXTRACTION PROCESS FOR: " + comuniList.toString());
try (Stream contrattiEAttrezzatureStream = contrattiAttrezzatureRepository.getReportContrattiAttrezzature(username, comuniList);
ByteArrayOutputStream out = new ByteArrayOutputStream();
Workbook workbook = generateExcelService.generateExcelStream(REPORT_3_CONTRATTI, contrattiEAttrezzatureStream);)
{
workbook.write(out);
if (workbook instanceof SXSSFWorkbook) {
((SXSSFWorkbook) workbook).dispose();
}
return out.toByteArray();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public Workbook generateExcelStream(String sheetName, Stream stream) {
logger.info("STARTING WRITING TO FILE: " + sheetName);
final int numberOfRowStoredInMemory = 100;
SXSSFWorkbook wb = new SXSSFWorkbook(numberOfRowStoredInMemory);
wb.setCompressTempFiles(Boolean.TRUE);
SXSSFSheet sheet = (SXSSFSheet) createSheet(sheetName, wb);
sheet.setRandomAccessWindowSize(100);
sheet.createFreezePane(0, 1);
AtomicInteger rowCount = new AtomicInteger(0);
AtomicReference[*]> fields = new AtomicReference(new ArrayList());
List headerNameList = new ArrayList();
Map fieldAlloweds = new HashMap();
Map>();
Map fieldGetterMethods = new HashMap();
stream.forEach(element -> {
if(rowCount.get() == 0) {
Class objectClass = element.getClass();
fields.set(getAllFields(objectClass));
for(Field field : fields.get()){
if (field.isAnnotationPresent(ExcludeFromExcel.class)) {
continue;
}
try {
Class 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) {
// Field ignored
}
}
writeHeaderLine(headerNameList, wb, sheet);
}
Row row = sheet.createRow(rowCount.incrementAndGet());
int columnCount = 0;
for (Field field : fields.get()){
if (field.isAnnotationPresent(ExcludeFromExcel.class)) {
continue;
}
Method fieldGetter = fieldGetterMethods.get(field.getName());
if(fieldGetter != null && fieldAlloweds.get(field.getName())){
Object fieldValue = null;
try {
fieldValue = fieldGetter.invoke(element);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new RuntimeException(e);
}
Class fieldType = fieldTypes.get(field.getName());
if (fieldValue == null) {
fieldValue = "";
fieldType = String.class;
}
createCell(row, columnCount++, fieldValue, fieldType, null);
}
}
if (rowCount.get() % numberOfRowStoredInMemory == 0) {
try {
((SXSSFSheet) sheet).flushRows(numberOfRowStoredInMemory);
} catch (IOException e) {
e.printStackTrace();
}
}
});
return wb;
}
@Query(nativeQuery = true, value = "...My very Long Long query...")
@QueryHints(value = {
@QueryHint(name = "javax.persistence.query.timeout", value = "1200000"),
@QueryHint(name = "org.hibernate.readOnly", value = "true"),
@QueryHint(name = "org.hibernate.fetchSize", value = "50")
})
Stream getReportContrattiAttrezzature(@Param("username") String username, List comuni);
Моя ситуация с использованием VisualVM такова

Вот изображение профиля потока моего Java-приложения, показывающее время выполнения и состояние различных потоков во время операции создания отчета Excel:

< /p>
Вопросы:
Правильно ли использовать Stream?
[*]Есть ли что-то, что я не учитываю?
[*]Как я могу повысить эффективность использования памяти с помощью моего подхода?
[*]Есть ли лучший вариант способ управления памятью с помощью Apache POI и больших наборов данных при использовании потоков?
Следует ли мне настроить конфигурацию SXSSFWorkbook или существует другая стратегия, которую мне следует рассмотреть, чтобы избежать исчерпания кучи?
Подробнее здесь: https://stackoverflow.com/questions/790 ... ook-and-pr