vluk@2fi-solutions.com.hk 4 дней назад
Родитель
Сommit
e592845c41
2 измененных файлов: 32 добавлений и 59 удалений
  1. +14
    -58
      src/main/java/com/ffii/fpsms/modules/report/service/ReportService.kt
  2. +18
    -1
      src/main/java/com/ffii/fpsms/modules/report/web/ReportController.kt

+ 14
- 58
src/main/java/com/ffii/fpsms/modules/report/service/ReportService.kt Просмотреть файл

@@ -6,11 +6,9 @@ import net.sf.jasperreports.engine.data.JRMapCollectionDataSource
import java.io.ByteArrayOutputStream import java.io.ByteArrayOutputStream
import java.io.InputStream import java.io.InputStream
import com.ffii.core.support.JdbcDao import com.ffii.core.support.JdbcDao
import org.apache.poi.ss.usermodel.Cell
import org.apache.poi.ss.usermodel.CellType
import org.apache.poi.ss.usermodel.Row
import org.apache.poi.ss.usermodel.Sheet
import org.apache.poi.xssf.usermodel.XSSFWorkbook
import net.sf.jasperreports.engine.export.ooxml.JRXlsxExporter
import net.sf.jasperreports.export.SimpleExporterInput
import net.sf.jasperreports.export.SimpleOutputStreamExporterOutput


@Service @Service
open class ReportService( open class ReportService(
@@ -933,61 +931,19 @@ fun searchMaterialStockOutTraceabilityReport(
return jdbcDao.queryForList("$finalSql ORDER BY itemNo, lotNo", args) return jdbcDao.queryForList("$finalSql ORDER BY itemNo, lotNo", args)
} }
/** /**
* Builds Stock Balance Report as Excel (.xlsx) from the same data used for the PDF report.
* Compiles and fills a Jasper Report, then exports to Excel (.xlsx). Same layout/columns as the report template.
*/ */
fun createStockBalanceExcel(dataList: List<Map<String, Any>>): ByteArray {
val workbook = XSSFWorkbook()
val sheet: Sheet = workbook.createSheet("Stock Balance")
val columns = listOf(
"itemNo" to "Item No",
"itemName" to "Item Name",
"unitOfMeasure" to "Unit",
"lotNo" to "Lot No",
"expiryDate" to "Expiry Date",
"openingBalance" to "Opening Balance",
"cumStockIn" to "Cum Stock In",
"cumStockOut" to "Cum Stock Out",
"currentBalance" to "Current Balance",
"storeLocation" to "Store Location",
"lastInDate" to "Last In Date",
"lastOutDate" to "Last Out Date",
"lastMovementDate" to "Last Movement Date",
"misInputAndLost" to "Mis Input And Lost",
"defectiveGoods" to "Defective Goods",
"variance" to "Variance",
"cumStockInByPurchaseOrder" to "Cum Stock In (PO)",
"cumStockInByJobOrder" to "Cum Stock In (JO)",
"cumStockInByStockTake" to "Cum Stock In (Stock Take)",
"cumStockInByAdj" to "Cum Stock In (Adj)",
"cumStockOutMissQty" to "Cum Stock Out Miss",
"cumStockOutBadQty" to "Cum Stock Out Bad",
"cumStockOutAdj" to "Cum Stock Out Adj",
"cumStockOutAdjStockTake" to "Cum Stock Out Adj Stock Take",
"cumStockOutStockTake" to "Cum Stock Out Stock Take",
"cumStockOutByDO" to "Cum Stock Out (DO)",
"cumStockOutByJO" to "Cum Stock Out (JO)",
"cumStockOutByConsumable" to "Cum Stock Out (Consumable)"
)
val headerRow: Row = sheet.createRow(0)
columns.forEachIndexed { index, (_, label) ->
val cell: Cell = headerRow.createCell(index, CellType.STRING)
cell.setCellValue(label)
}
dataList.forEachIndexed { rowIndex, rowData ->
val row: Row = sheet.createRow(rowIndex + 1)
columns.forEachIndexed { colIndex, (key, _) ->
val cell: Cell = row.createCell(colIndex)
val value = rowData[key]
when (value) {
null -> cell.setCellValue("")
is Number -> cell.setCellValue(value.toDouble())
else -> cell.setCellValue(value.toString())
}
}
}
columns.indices.forEach { sheet.autoSizeColumn(it) }
fun createExcelResponse(templatePath: String, params: Map<String, Any>, dataList: List<Map<String, Any>>): 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 out = ByteArrayOutputStream()
workbook.use { it.write(out) }
val exporter = JRXlsxExporter()
exporter.setExporterInput(SimpleExporterInput(jasperPrint))
exporter.setExporterOutput(SimpleOutputStreamExporterOutput(out))
exporter.exportReport()
return out.toByteArray() return out.toByteArray()
} }




+ 18
- 1
src/main/java/com/ffii/fpsms/modules/report/web/ReportController.kt Просмотреть файл

@@ -268,6 +268,19 @@ class ReportController(
@RequestParam(required = false) lastOutDateStart: String?, @RequestParam(required = false) lastOutDateStart: String?,
@RequestParam(required = false) lastOutDateEnd: String? @RequestParam(required = false) lastOutDateEnd: String?
): ResponseEntity<ByteArray> { ): ResponseEntity<ByteArray> {
val parameters = mutableMapOf<String, Any>()
parameters["stockCategory"] = stockCategory ?: "All"
parameters["itemNo"] = itemCode ?: "All"
parameters["reportDate"] = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))
parameters["reportTime"] = LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"))
parameters["storeLocation"] = storeLocation ?: ""
parameters["balanceFilterStart"] = balanceFilterStart ?: ""
parameters["balanceFilterEnd"] = balanceFilterEnd ?: ""
parameters["lastInDateStart"] = lastInDateStart ?: ""
parameters["lastInDateEnd"] = lastInDateEnd ?: ""
parameters["lastOutDateStart"] = lastOutDateStart ?: ""
parameters["lastOutDateEnd"] = lastOutDateEnd ?: ""

val dbData = reportService.searchStockBalanceReport( val dbData = reportService.searchStockBalanceReport(
stockCategory, stockCategory,
itemCode, itemCode,
@@ -280,7 +293,11 @@ class ReportController(
lastOutDateEnd lastOutDateEnd
) )


val excelBytes = reportService.createStockBalanceExcel(dbData)
val excelBytes = reportService.createExcelResponse(
"/jasper/StockBalanceReport.jrxml",
parameters,
dbData
)


val headers = HttpHeaders().apply { val headers = HttpHeaders().apply {
contentType = MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") contentType = MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")


Загрузка…
Отмена
Сохранить