Writing large data around 1/2 million records with 25 columns.
Using apache-poi streaming workbook to write data from list to excel file. when tested locally it is giving high CPU spikes in local machine too. appears to be causing when writing workbook data to file
workbook.write(fileOutputStream) // it is causing CPU spikes debugged and confirmed.
It is causing high CPU usage in cloud app (deployed in kubernetes) and restarting application as it is hitting resource limits. we have a simple app with 2042Mi memory and 1024m CPU config.
Is there any way to write a large excel file without impacting CPU and Memory and java heap efficiently.
(NOTE: can't use csv or other formats as business requirement is for excel files)
Code using:
import java.io.File;
import java.io.FileOutputStream;
import java.util.List;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.stereotype.Service;
import com.king.medicalcollege.model.Medico;
@Service
public class ExcelWriterService {
// file is an empty file already created
// Large List around 500K records of medico data [Medico is POJO]
public File writeData(File file, List<Medico> medicos) {
SXSSFWorkbook sxssfWorkbook = null;
try (SXSSFWorkbook workbook = sxssfWorkbook = new SXSSFWorkbook(1);
FileOutputStream fileOutputStream = new FileOutputStream(file)) {
Sheet sheet = workbook.createSheet();
CellStyle cellStyle = workbook.createCellStyle();
int rowNum = 0;
for (Medico medico : medicos) {
Row row = sheet.createRow(rowNum);
//just adding POJO values (25 fields) into ROW
addDataInRow(medico, row, cellStyle);
rowNum++;
}
//workbook.write causing CPU spike
workbook.write(fileOutputStream);
workbook.dispose();
} catch (Exception exception) {
return null;
} finally {
if (sxssfWorkbook != null) {
sxssfWorkbook.dispose();
}
}
return file;
}
private void addDataInRow(Medico medico, Row row, CellStyle cellStyle) {
Cell cell_0 = row.createCell(0);
cell_0.setCellValue(medico.getFirstName());
cell_0.setCellStyle(cellStyle);
Cell cell_1 = row.createCell(1);
cell_1.setCellValue(medico.getMiddleName());
cell_1.setCellStyle(cellStyle);
Cell cell_2 = row.createCell(2);
cell_2.setCellValue(medico.getLastName());
cell_2.setCellStyle(cellStyle);
Cell cell_3 = row.createCell(2);
cell_3.setCellValue(medico.getFirstName());
cell_3.setCellStyle(cellStyle);
//...... around 25 columns will be added like this
}
}