Экспортируйте данные из базы данных порциями.
Записывайте каждый фрагмент в файл Excel.
Сжимайте и загружайте каждый фрагмент на Amazon. Корзина S3.
Предоставьте пользователям конечную точку для загрузки полного файла Excel.
Я использую Apache POI для создания файлов Excel и AWS SDK для Java для управления загрузками S3. Однако я сталкиваюсь с проблемами нехватки памяти при попытке объединить и сжать эти большие фрагменты в один файл для загрузки.
Вот упрощенная версия моей текущей реализации:
Вот упрощенная версия моей текущей реализации:
Вот упрощенная версия моей текущей реализации:
p>
Экспорт данных частями:
Код: Выделить всё
@Service
public class DataExportService {
@Autowired
private YourRepository repository;
@Autowired
private S3Client s3Client;
@Value("${aws.s3.bucket}")
private String bucketName;
public void exportData() {
int pageSize = 10000;
int pageNumber = 0;
List records;
while (!(records = repository.findAll(PageRequest.of(pageNumber, pageSize))).isEmpty()) {
// Create a new Excel file for each chunk
try (SXSSFWorkbook workbook = new SXSSFWorkbook()) {
Sheet sheet = workbook.createSheet("Data");
writeDataToSheet(sheet, records);
// Save the workbook to a temporary file
File tempFile = File.createTempFile("data_chunk_" + pageNumber, ".xlsx");
try (FileOutputStream outputStream = new FileOutputStream(tempFile)) {
workbook.write(outputStream);
}
// Upload the file to S3
uploadToS3(tempFile, "data_chunk_" + pageNumber + ".xlsx");
} catch (IOException e) {
e.printStackTrace();
}
pageNumber++;
}
}
private void writeDataToSheet(Sheet sheet, List records) {
int rowCount = 0;
for (YourEntity record : records) {
Row row = sheet.createRow(rowCount++);
row.createCell(0).setCellValue(record.getField1());
}
}
private void uploadToS3(File file, String key) {
try {
PutObjectRequest request = PutObjectRequest.builder()
.bucket(bucketName)
.key(key)
.build();
s3Client.putObject(request, RequestBody.fromFile(file));
} catch (S3Exception e) {
e.printStackTrace();
}
}
}
Код: Выделить всё
@RestController
public class DownloadController {
@Autowired
private S3Client s3Client;
@Value("${aws.s3.bucket}")
private String bucketName;
@GetMapping("/download")
public void downloadMergedFile(HttpServletResponse response) throws IOException {
List keys = List.of("data_chunk_0.xlsx", "data_chunk_1.xlsx"); // Add all keys
response.setContentType("application/zip");
response.setHeader("Content-Disposition", "attachment; filename=merged_data.xlsx.zip");
try (ServletOutputStream outputStream = response.getOutputStream();
ZipOutputStream zipOut = new ZipOutputStream(outputStream)) {
ZipEntry zipEntry = new ZipEntry("merged_data.xlsx");
zipOut.putNextEntry(zipEntry);
try (SXSSFWorkbook workbook = new SXSSFWorkbook()) {
for (String key : keys) {
try (InputStream inputStream = downloadFromS3(key);
XSSFWorkbook partWorkbook = new XSSFWorkbook(inputStream)) {
for (int i = 0; i < partWorkbook.getNumberOfSheets(); i++) {
Sheet partSheet = partWorkbook.getSheetAt(i);
Sheet mergedSheet = workbook.createSheet(partSheet.getSheetName() + "_" + i);
copySheet(partSheet, mergedSheet);
}
}
}
workbook.write(zipOut);
zipOut.closeEntry();
}
}
}
private InputStream downloadFromS3(String key) {
GetObjectRequest request = GetObjectRequest.builder()
.bucket(bucketName)
.key(key)
.build();
ResponseBytes objectBytes = s3Client.getObjectAsBytes(request);
return objectBytes.asInputStream();
}
private void copySheet(Sheet source, Sheet destination) {
for (Row srcRow : source) {
Row destRow = destination.createRow(srcRow.getRowNum());
for (Cell srcCell : srcRow) {
Cell destCell = destRow.createCell(srcCell.getColumnIndex());
switch (srcCell.getCellType()) {
case STRING:
destCell.setCellValue(srcCell.getStringCellValue());
break;
case NUMERIC:
destCell.setCellValue(srcCell.getNumericCellValue());
break;
case BOOLEAN:
destCell.setCellValue(srcCell.getBooleanCellValue());
break;
case FORMULA:
destCell.setCellFormula(srcCell.getCellFormula());
break;
default:
break;
}
}
}
}
}
- Как оптимизировать этот процесс, чтобы избежать проблем с нехваткой памяти, когда
объединять большие фрагменты Excel? - Существуют ли какие-либо передовые методы или
альтернативные подходы для обработки экспорта больших файлов с ограниченной
памятью в Spring Boot и S3? - Есть ли способ более эффективно выполнять процесс слияния
и сжатия в рамках ограничений
моей текущей настройки?
Подробнее здесь: https://stackoverflow.com/questions/788 ... ng-boot-an