Files
spring-boot-demo/excel-export

excel-export

Companion code for Export Excel and CSV from Spring Boot: Streaming 1 Million Rows with Apache POI SXSSF.

Spring Boot 4.1.2, Spring Framework 7, JDK 25, Apache POI 6.0.0 (poi-ooxml), OpenCSV 5.12.0. No database, no Docker.

Piece Code What it shows
XSSF endpoint ExportController#xssf whole workbook in heap; the baseline that runs out of memory
SXSSF endpoint ExportController#sxssf SXSSFWorkbook(100) + StreamingResponseBody, dispose() in finally, optional compressTempFiles
CSV endpoint ExportController#csv, CsvExporter OpenCSV streaming, UTF-8 BOM for Excel, formula-injection guard, swallowed write errors
Writer shared by XSSF and SXSSF XlsxExporter styles created once, freeze pane, auto filter, lakh/crore number format, sheet rolling at 1,048,576 rows
Data SaleSource rows computed from their index (stands in for a database cursor)
Diagnostics ProbeController peak used heap and peak RSS; delete before shipping
./scripts/run-all.sh                      # tests + every measurement; rewrites output/*.txt (15-25 minutes)
curl -o sales.xlsx 'http://localhost:8080/export/sxssf?rows=1000000'    # after: java -jar target/excel-export-1.0.0.jar

output/01..04 come from the tests, output/05..09 from scripts/measure.sh, output/10 from scripts/libreoffice-check.sh, which starts a fresh JVM with a fixed -Xmx for every line. The numbers are indicative: they were taken on a shared 2-vCPU sandbox, one run per line.

Not run here: a real database cursor (rows are generated) and Microsoft Excel itself. LibreOffice 24.2.7.2 refuses to open the SXSSF file because its ZIP entries carry a zero timestamp (same with POI 5.5.1); see output/10-libreoffice.txt.