|
|
@@ -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() |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|