|
|
|
@@ -19,6 +19,7 @@ import org.apache.poi.ss.util.CellRangeAddress |
|
|
|
import org.apache.poi.ss.util.WorkbookUtil |
|
|
|
import org.apache.poi.xssf.streaming.SXSSFWorkbook |
|
|
|
import java.io.ByteArrayOutputStream |
|
|
|
import java.util.Locale |
|
|
|
|
|
|
|
@RestController |
|
|
|
@RequestMapping("/report") |
|
|
|
@@ -32,7 +33,7 @@ class StockLedgerReportController( |
|
|
|
val header: CellStyle, |
|
|
|
val text: CellStyle, |
|
|
|
val center: CellStyle, |
|
|
|
val int: CellStyle, |
|
|
|
val number: CellStyle, |
|
|
|
val dash: CellStyle, |
|
|
|
val sumQty: CellStyle, |
|
|
|
val sumLabel: CellStyle, |
|
|
|
@@ -166,7 +167,7 @@ class StockLedgerReportController( |
|
|
|
borderLeft = BorderStyle.THIN |
|
|
|
borderRight = BorderStyle.THIN |
|
|
|
} |
|
|
|
val intStyle = workbook.createCellStyle().apply { |
|
|
|
val numberStyle = workbook.createCellStyle().apply { |
|
|
|
alignment = HorizontalAlignment.RIGHT |
|
|
|
verticalAlignment = VerticalAlignment.CENTER |
|
|
|
borderTop = BorderStyle.THIN |
|
|
|
@@ -174,7 +175,7 @@ class StockLedgerReportController( |
|
|
|
borderLeft = BorderStyle.THIN |
|
|
|
borderRight = BorderStyle.THIN |
|
|
|
val df: DataFormat = workbook.createDataFormat() |
|
|
|
dataFormat = df.getFormat("#,##0") |
|
|
|
dataFormat = df.getFormat("#,##0.##") |
|
|
|
} |
|
|
|
val dashStyle = workbook.createCellStyle().apply { |
|
|
|
alignment = HorizontalAlignment.RIGHT |
|
|
|
@@ -188,7 +189,7 @@ class StockLedgerReportController( |
|
|
|
alignment = HorizontalAlignment.RIGHT |
|
|
|
verticalAlignment = VerticalAlignment.CENTER |
|
|
|
val df: DataFormat = workbook.createDataFormat() |
|
|
|
dataFormat = df.getFormat("#,##0") |
|
|
|
dataFormat = df.getFormat("#,##0.##") |
|
|
|
borderTop = BorderStyle.THICK |
|
|
|
borderBottom = BorderStyle.THICK |
|
|
|
borderLeft = BorderStyle.THIN |
|
|
|
@@ -230,7 +231,7 @@ class StockLedgerReportController( |
|
|
|
header = headerStyle, |
|
|
|
text = textStyle, |
|
|
|
center = centerStyle, |
|
|
|
int = intStyle, |
|
|
|
number = numberStyle, |
|
|
|
dash = dashStyle, |
|
|
|
sumQty = sumQty, |
|
|
|
sumLabel = sumLabel, |
|
|
|
@@ -255,11 +256,11 @@ class StockLedgerReportController( |
|
|
|
return if (negative) -n else n |
|
|
|
} |
|
|
|
|
|
|
|
private fun setIntCellFromFormatted( |
|
|
|
private fun setNumberCellFromFormatted( |
|
|
|
row: Row, |
|
|
|
col: Int, |
|
|
|
value: Any?, |
|
|
|
intStyle: CellStyle, |
|
|
|
numberStyle: CellStyle, |
|
|
|
dashStyle: CellStyle, |
|
|
|
) { |
|
|
|
val cell = row.createCell(col) |
|
|
|
@@ -270,15 +271,20 @@ class StockLedgerReportController( |
|
|
|
return |
|
|
|
} |
|
|
|
if (parsed < 0) { |
|
|
|
val s = "%,d".format(kotlin.math.abs(parsed).toLong()) |
|
|
|
cell.setCellValue("($s)") |
|
|
|
cell.setCellValue("(${formatAbsQty(parsed)})") |
|
|
|
cell.cellStyle = dashStyle |
|
|
|
} else { |
|
|
|
cell.setCellValue(parsed) |
|
|
|
cell.cellStyle = intStyle |
|
|
|
cell.cellStyle = numberStyle |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** Up to 2 dp; strip trailing zeros so whole numbers stay whole. */ |
|
|
|
private fun formatAbsQty(v: Double): String { |
|
|
|
val formatted = "%,.2f".format(Locale.US, kotlin.math.abs(v)) |
|
|
|
return formatted.trimEnd('0').trimEnd('.') |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* SXSSF keeps only a sliding window of rows in memory to avoid OOM on large exports. |
|
|
|
*/ |
|
|
|
@@ -353,9 +359,9 @@ class StockLedgerReportController( |
|
|
|
r.createCell(c).apply { setCellValue(""); cellStyle = styles.sumEmpty } |
|
|
|
} |
|
|
|
r.getCell(7).apply { setCellValue("貨品總量:"); cellStyle = styles.sumLabel } |
|
|
|
setIntCellFromFormatted(r, 8, totalIn, styles.sumQty, styles.dash) |
|
|
|
setIntCellFromFormatted(r, 9, totalOut, styles.sumQty, styles.dash) |
|
|
|
setIntCellFromFormatted(r, 10, totalBal, styles.sumQty, styles.dash) |
|
|
|
setNumberCellFromFormatted(r, 8, totalIn, styles.sumQty, styles.dash) |
|
|
|
setNumberCellFromFormatted(r, 9, totalOut, styles.sumQty, styles.dash) |
|
|
|
setNumberCellFromFormatted(r, 10, totalBal, styles.sumQty, styles.dash) |
|
|
|
} |
|
|
|
|
|
|
|
if (dbData.isEmpty()) { |
|
|
|
@@ -397,10 +403,10 @@ class StockLedgerReportController( |
|
|
|
setTextCell(r, 4, typeText, styles.center) |
|
|
|
setTextCell(r, 5, m["lotNo"], styles.text) |
|
|
|
setTextCell(r, 6, m["expiryDate"], styles.center) |
|
|
|
setIntCellFromFormatted(r, 7, m["cumOpeningBal"], styles.int, styles.dash) |
|
|
|
setIntCellFromFormatted(r, 8, m["stockIn"], styles.int, styles.dash) |
|
|
|
setIntCellFromFormatted(r, 9, m["stockOut"], styles.int, styles.dash) |
|
|
|
setIntCellFromFormatted(r, 10, m["cumBalance"], styles.int, styles.dash) |
|
|
|
setNumberCellFromFormatted(r, 7, m["cumOpeningBal"], styles.number, styles.dash) |
|
|
|
setNumberCellFromFormatted(r, 8, m["stockIn"], styles.number, styles.dash) |
|
|
|
setNumberCellFromFormatted(r, 9, m["stockOut"], styles.number, styles.dash) |
|
|
|
setNumberCellFromFormatted(r, 10, m["cumBalance"], styles.number, styles.dash) |
|
|
|
setTextCell(r, 11, m["orderRefNo"], styles.text) |
|
|
|
setTextCell(r, 12, m["storeLocation"], styles.center) |
|
|
|
|
|
|
|
|