diff --git a/src/main/java/com/ffii/fpsms/modules/report/service/ReportService.kt b/src/main/java/com/ffii/fpsms/modules/report/service/ReportService.kt index bbce6b3..7bcfcb7 100644 --- a/src/main/java/com/ffii/fpsms/modules/report/service/ReportService.kt +++ b/src/main/java/com/ffii/fpsms/modules/report/service/ReportService.kt @@ -3,8 +3,12 @@ package com.ffii.fpsms.modules.report.service import org.springframework.stereotype.Service import net.sf.jasperreports.engine.* import net.sf.jasperreports.engine.data.JRMapCollectionDataSource +import java.io.ByteArrayOutputStream import java.io.InputStream import com.ffii.core.support.JdbcDao +import net.sf.jasperreports.engine.export.ooxml.JRXlsxExporter +import net.sf.jasperreports.export.SimpleExporterInput +import net.sf.jasperreports.export.SimpleOutputStreamExporterOutput @Service open class ReportService( @@ -926,6 +930,23 @@ fun searchMaterialStockOutTraceabilityReport( } return jdbcDao.queryForList("$finalSql ORDER BY itemNo, lotNo", args) } + /** + * Compiles and fills a Jasper Report, then exports to Excel (.xlsx). Same layout/columns as the report template. + */ + fun createExcelResponse(templatePath: String, params: Map, dataList: List>): ByteArray { + val stream = this::class.java.getResourceAsStream(templatePath) + ?: throw RuntimeException("Report template not found: $templatePath") + val jasperReport = JasperCompileManager.compileReport(stream) + val dataSource = JRMapCollectionDataSource(dataList) + val jasperPrint = JasperFillManager.fillReport(jasperReport, params, dataSource) + val out = ByteArrayOutputStream() + val exporter = JRXlsxExporter() + exporter.setExporterInput(SimpleExporterInput(jasperPrint)) + exporter.setExporterOutput(SimpleOutputStreamExporterOutput(out)) + exporter.exportReport() + return out.toByteArray() + } + /** * Compiles and fills a Jasper Report, returning the PDF as a ByteArray. */ diff --git a/src/main/java/com/ffii/fpsms/modules/report/web/ReportController.kt b/src/main/java/com/ffii/fpsms/modules/report/web/ReportController.kt index 87b2631..710fdac 100644 --- a/src/main/java/com/ffii/fpsms/modules/report/web/ReportController.kt +++ b/src/main/java/com/ffii/fpsms/modules/report/web/ReportController.kt @@ -269,8 +269,6 @@ class ReportController( @RequestParam(required = false) lastOutDateEnd: String? ): ResponseEntity { val parameters = mutableMapOf() - - // Set report header parameters parameters["stockCategory"] = stockCategory ?: "All" parameters["itemNo"] = itemCode ?: "All" parameters["reportDate"] = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) @@ -282,7 +280,7 @@ class ReportController( parameters["lastInDateEnd"] = lastInDateEnd ?: "" parameters["lastOutDateStart"] = lastOutDateStart ?: "" parameters["lastOutDateEnd"] = lastOutDateEnd ?: "" - + val dbData = reportService.searchStockBalanceReport( stockCategory, itemCode, @@ -294,20 +292,20 @@ class ReportController( lastOutDateStart, lastOutDateEnd ) - - val pdfBytes = reportService.createPdfResponse( - "/jasper/StockBalanceReport.jrxml", - parameters, + + val excelBytes = reportService.createExcelResponse( + "/jasper/StockBalanceReport.jrxml", + parameters, dbData ) - + val headers = HttpHeaders().apply { - contentType = MediaType.APPLICATION_PDF - setContentDispositionFormData("attachment", "StockBalanceReport.pdf") - set("filename", "StockBalanceReport.pdf") + contentType = MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") + setContentDispositionFormData("attachment", "StockBalanceReport.xlsx") + set("filename", "StockBalanceReport.xlsx") } - - return ResponseEntity(pdfBytes, headers, HttpStatus.OK) + + return ResponseEntity(excelBytes, headers, HttpStatus.OK) } } \ No newline at end of file