写入包含25列的约50万条记录的大型数据。
使用apache-poi流式工作簿将数据从列表写入excel文件。在本地测试时,它也会在本地计算机中产生高CPU峰值。似乎是在将工作簿数据写入文件时造成的
workbook.write(fileOutputStream) // it is causing CPU spikes debugged and confirmed.
它导致云应用程序(部署在Kubernetes)中的CPU使用率较高,并在达到资源限制时重新启动应用程序。我们有一个简单的应用程序,具有2042 Mi内存和1024 m CPU配置。
有没有办法写一个大的excel文件,而不影响CPU和内存和java堆有效。
(NOTE:不能使用csv或其他格式,因为业务要求是excel文件)
代码使用:
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
}
}
1条答案
按热度按时间cygmwpex1#
你给SXSSFWorkbook一个窗口大小似乎是正确的(尽管
1
可能太小而导致问题?)。当行数超过你设置的限制时,工作簿应该被刷新到磁盘,减少内存使用。我怀疑是否有减少cpu使用的解决方案。您可以尝试通过调整JVM参数来限制内存使用,这样就不会触发K8s限制。x一个月一个月x一个月二个月一个月x一个月三个月一个月x一个月四个月
您是否考虑过使用其他库来编写Excel文件?例如,请看下面的SO答案:Are there any alternatives to using Apache POI Java for Microsoft Office?