diff --git a/Controllers/Expenses.Controller.cs b/Controllers/Expenses.Controller.cs index 832c85b..b2b2a2b 100644 --- a/Controllers/Expenses.Controller.cs +++ b/Controllers/Expenses.Controller.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Net; using ClosedXML.Excel; using FastReport; @@ -21,176 +22,157 @@ namespace rmutr_report.Controllers { this._setting = setting; } + + /// ระดับชั้นของแต่ละแถว อนุมานจาก "no" (จำนวนจุด) หรือ prefix ของ expenditure_budget + /// เมื่อไม่มี "no" — ใช้กำหนดว่าแถวไหนเป็นแถวสรุปยอด (มีลูก) ต้องใส่สูตรรวม แทนตัวเลขคงที่ + private static int GetDepth(operating_expenses_detail item) + { + if (!string.IsNullOrEmpty(item.no)) return item.no.Count(c => c == '.'); + if (item.expenditure_budget != null && item.expenditure_budget.StartsWith(" - ")) return 4; + if (item.expenditure_budget != null && item.expenditure_budget.StartsWith(" - ")) return 3; + return 0; + } + [HttpPost, Route("reports/operating_expenses/{type}")] [ApiExplorerSettings(GroupName = "reports")] public IActionResult GetExpensesReport([FromRoute] string type, [FromBody] operating_expenses _operating_expenses) { - var _operating_expensess = new List() { _operating_expenses }; - - Report report = new Report(); - report.Load(_setting.report_path + "operating_expenses.frx"); - report.RegisterData(_operating_expensess, "operating_expenses"); - report.Prepare(); - - MemoryStream stream = new MemoryStream(); switch (type) { - case "pdf": - PDFExport pdf = new PDFExport(); - report.Export(pdf, stream); - stream.Seek(0, SeekOrigin.Begin); - return File(stream, "application/pdf"); case "xls": case "xlsx": - Excel2007Export excel = new Excel2007Export(); - report.Export(excel, stream); - stream.Seek(0, SeekOrigin.Begin); - //return File(stream, "application/vnd.ms-excel"); - string date = DateTime.Now.ToString("yyyyMMddHHmmss"); + { + using var workbook = new XLWorkbook(); + var ws = workbook.Worksheets.Add("ค่าใช้จ่ายดำเนินงาน"); + + ws.Column(1).Width = 11.03; + ws.Column(2).Width = 83.48; + ws.Column(3).Width = 26.77; + ws.Column(4).Width = 61.42; + + void TitleRow(int row, string text, bool rightAlign = false) + { + var range = ws.Range(row, 1, row, 4).Merge(); + range.Value = text; + range.Style.Font.FontName = "TH Sarabun New"; + range.Style.Font.FontSize = 16; + range.Style.Font.Bold = true; + range.Style.Alignment.WrapText = true; + range.Style.Alignment.Vertical = XLAlignmentVerticalValues.Center; + range.Style.Alignment.Horizontal = rightAlign + ? XLAlignmentHorizontalValues.Right + : XLAlignmentHorizontalValues.Center; + } + + TitleRow(1, $"ปีงบประมาณ {_operating_expenses.budget_year} {_operating_expenses.plan}"); + TitleRow(2, _operating_expenses.text); + TitleRow(3, $"{_operating_expenses.faculty_name_th} {_operating_expenses.budget_location_name_th}"); + TitleRow(4, $"หน่วย : {_operating_expenses.total_amount:N0} บาท", rightAlign: true); + // แถว 5 เว้นว่างไว้ (ตามรูปแบบรายงานเดิม) + + const int headerRow = 6; + var headers = new[] + { + "ลำดับที่", "งบรายจ่าย", $"คำขอตั้ง\nปี {_operating_expenses.request_year}", "สรุปคำชี้แจง" + }; + for (var col = 1; col <= 4; col++) + { + var cell = ws.Cell(headerRow, col); + cell.Value = headers[col - 1]; + cell.Style.Font.FontName = "TH Sarabun New"; + cell.Style.Font.FontSize = 16; + cell.Style.Font.Bold = true; + cell.Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center; + cell.Style.Alignment.Vertical = XLAlignmentVerticalValues.Center; + cell.Style.Alignment.WrapText = true; + cell.Style.Border.OutsideBorder = XLBorderStyleValues.Thin; + cell.Style.Border.InsideBorder = XLBorderStyleValues.Thin; + } + + var data = _operating_expenses.data ?? new List(); + var depths = data.Select(GetDepth).ToList(); + var startRow = headerRow + 1; + + for (var i = 0; i < data.Count; i++) + { + var row = startRow + i; + var item = data[i]; + var depth = depths[i]; + + // ลูกโดยตรง = แถวถัดไปที่ลึกกว่าพอดี 1 ชั้น หยุดเมื่อเจอแถวที่ลึกเท่ากันหรือตื้นกว่า + var childRows = new List(); + for (var j = i + 1; j < data.Count && depths[j] > depth; j++) + { + if (depths[j] == depth + 1) childRows.Add(startRow + j); + } + + ws.Cell(row, 1).Value = item.no; + ws.Cell(row, 2).Value = item.expenditure_budget; + if (childRows.Any()) + { + ws.Cell(row, 3).FormulaA1 = "=" + string.Join("+", childRows.Select(r => $"C{r}")); + } + else + { + ws.Cell(row, 3).Value = item.amount ?? 0; + } + ws.Cell(row, 4).Value = item.clarification_summary; + + var range = ws.Range(row, 1, row, 4); + range.Style.Font.FontName = "TH Sarabun New"; + range.Style.Font.FontSize = 14; + range.Style.Alignment.WrapText = true; + range.Style.Alignment.Vertical = XLAlignmentVerticalValues.Center; + range.Style.Border.OutsideBorder = XLBorderStyleValues.Thin; + range.Style.Border.InsideBorder = XLBorderStyleValues.Thin; + + ws.Cell(row, 1).Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center; + ws.Cell(row, 2).Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Left; + ws.Cell(row, 3).Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Right; + ws.Cell(row, 3).Style.NumberFormat.Format = "#,##0_);(#,##0)"; + ws.Cell(row, 4).Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Left; + } + + using var xlsStream = new MemoryStream(); + workbook.SaveAs(xlsStream); + xlsStream.Seek(0, SeekOrigin.Begin); + var xlsDate = DateTime.Now.ToString("yyyyMMddHHmmss"); return File( - stream, + xlsStream.ToArray(), "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", - "operating_expenses_"+date + ".xlsx"); - break; + "operating_expenses_" + xlsDate + ".xlsx"); + } + case "pdf": case "doc": case "docx": - Word2007Export word = new Word2007Export(); - report.Export(word, stream); - stream.Seek(0, SeekOrigin.Begin); - return File(stream, "appllication/vnd.ms-word"); - break; + { + var _operating_expensess = new List() { _operating_expenses }; + + Report report = new Report(); + report.Load(_setting.report_path + "operating_expenses.frx"); + report.RegisterData(_operating_expensess, "operating_expenses"); + report.Prepare(); + + MemoryStream stream = new MemoryStream(); + if (type == "pdf") + { + PDFExport pdf = new PDFExport(); + report.Export(pdf, stream); + stream.Seek(0, SeekOrigin.Begin); + return File(stream, "application/pdf"); + } + else + { + Word2007Export word = new Word2007Export(); + report.Export(word, stream); + stream.Seek(0, SeekOrigin.Begin); + return File(stream, "appllication/vnd.ms-word"); + } + } } return Ok(); } - //{ - // var workbook = new XLWorkbook(); - // var ws = workbook.Worksheets.Add("ค่าใช้จ่ายดำเนินงาน"); - // ws.Range("A1:D1").Merge().Value = "ปีงบประมาณ " + _operating_expenses.budget_year + " แผน " + _operating_expenses.plan; - // ws.Range("A1:D1").Style.Alignment.WrapText = true; - // ws.Range("A1:D1").Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center; - // ws.Range("A1:D1").Style.Alignment.Vertical = XLAlignmentVerticalValues.Center; - // ws.Cell("A1").Style.Font.FontName = "TH SarabunPSK"; - // ws.Cell("A1").Style.Font.FontSize = 14; - // ws.Range("A1:D1").Style.Font.Bold = true; - // ws.Range("A2:D2").Merge().Value = "ผลผลิต " + _operating_expenses.product+ " หน่วยงาน " + _operating_expenses.agency + " พื้นที่ "+_operating_expenses.area; - // ws.Range("A2:D2").Style.Alignment.WrapText = true; - // ws.Range("A2:D2").Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center; - // ws.Range("A2:D2").Style.Alignment.Vertical = XLAlignmentVerticalValues.Center; - // ws.Cell("A2").Style.Font.FontName = "TH SarabunPSK"; - // ws.Cell("A2").Style.Font.FontSize = 14; - // ws.Range("A2:D2").Style.Font.Bold = true; - // ws.Cell("D3").Value = "หน่วย : "+ _operating_expenses.total_amount +" บาท"; - // ws.Cell("D3").Style.Font.FontName = "TH SarabunPSK"; - // ws.Cell("D3").Style.Font.FontSize = 14; - // ws.Cell("D3").Style.Font.Bold = true; - // ws.Cell("D3").Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Right; - // ws.Cell("D3").Style.Alignment.Vertical = XLAlignmentVerticalValues.Center; - // //ws.Cell("D3").DataType = XLDataType.Number; - // ws.Cell("D3").Style.NumberFormat.NumberFormatId = 2; - // ws.Cell("A4").Value = "ลำดับที่"; - // ws.Cell("A4").Style.Font.FontName = "TH SarabunPSK"; - // ws.Cell("A4").Style.Font.FontSize = 14; - // ws.Cell("A4").Style.Font.Bold = true; - // ws.Cell("A4").Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center; - // ws.Cell("A4").Style.Alignment.Vertical = XLAlignmentVerticalValues.Center; - // ws.Cell("A4").Style.Border.TopBorder = XLBorderStyleValues.Thin; - // ws.Cell("A4").Style.Border.RightBorder = XLBorderStyleValues.Thin; - // ws.Cell("A5").Style.Border.TopBorder = XLBorderStyleValues.Thin; - // ws.Cell("A5").Style.Border.RightBorder = XLBorderStyleValues.Thin; - // ws.Cell("B4").Value = "งบรายจ่าย"; - // ws.Cell("B4").Style.Font.FontName = "TH SarabunPSK"; - // ws.Cell("B4").Style.Font.FontSize = 14; - // ws.Cell("B4").Style.Font.Bold = true; - // ws.Cell("B4").Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center; - // ws.Cell("B4").Style.Alignment.Vertical = XLAlignmentVerticalValues.Center; - // ws.Cell("B4").Style.Border.TopBorder = XLBorderStyleValues.Thin; - // ws.Cell("B4").Style.Border.RightBorder = XLBorderStyleValues.Thin; - // ws.Cell("B5").Style.Border.TopBorder = XLBorderStyleValues.Thin; - // ws.Cell("B5").Style.Border.RightBorder = XLBorderStyleValues.Thin; - // ws.Cell("C4").Value = "คำขอตั้ง"; - // ws.Cell("C4").Style.Font.FontName = "TH SarabunPSK"; - // ws.Cell("C4").Style.Font.FontSize = 14; - // ws.Cell("C4").Style.Font.Bold = true; - // ws.Cell("C4").Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center; - // ws.Cell("C4").Style.Alignment.Vertical = XLAlignmentVerticalValues.Center; - // ws.Cell("C4").Style.Border.TopBorder = XLBorderStyleValues.Thin; - // ws.Cell("C4").Style.Border.RightBorder = XLBorderStyleValues.Thin; - // ws.Cell("C5").Style.Border.TopBorder = XLBorderStyleValues.Thin; - // ws.Cell("C5").Style.Border.RightBorder = XLBorderStyleValues.Thin; - // ws.Cell("D4").Value = "สรุปคำชี้แจง"; - // ws.Cell("D4").Style.Font.FontName = "TH SarabunPSK"; - // ws.Cell("D4").Style.Font.FontSize = 14; - // ws.Cell("D4").Style.Font.Bold = true; - // ws.Cell("D4").Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center; - // ws.Cell("D4").Style.Alignment.Vertical = XLAlignmentVerticalValues.Center; - // ws.Cell("D4").Style.Border.TopBorder = XLBorderStyleValues.Thin; - // ws.Cell("D4").Style.Border.RightBorder = XLBorderStyleValues.Thin; - // ws.Cell("D5").Style.Border.TopBorder = XLBorderStyleValues.Thin; - // ws.Cell("D5").Style.Border.RightBorder = XLBorderStyleValues.Thin; - // ws.Cell("A5").Style.Border.TopBorder = XLBorderStyleValues.None; - // ws.Cell("B5").Style.Border.TopBorder = XLBorderStyleValues.None; - // ws.Cell("C5").Style.Border.TopBorder = XLBorderStyleValues.None; - // ws.Cell("D5").Style.Border.TopBorder = XLBorderStyleValues.None; - // - // ws.Column(1).Width = 10; - // ws.Column(2).Width = 40; - // ws.Column(3).Width = 30; - // ws.Column(4).Width = 50; - // int row = 6; - // ws.Cell(row, 3).SetDataType(XLDataType.Number); - // if (_operating_expenses != null) - // { - // ws.Cell("C5").Value = "ปี "+_operating_expenses.request_year; - // ws.Cell("C5").Style.Alignment.WrapText = true; - // ws.Cell("C5").Style.Font.FontName = "TH SarabunPSK"; - // ws.Cell("C5").Style.Font.FontSize = 14; - // ws.Cell("C5").Style.Font.Bold = true; - // ws.Cell("C5").Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center; - // ws.Cell("C5").Style.Alignment.Vertical = XLAlignmentVerticalValues.Center; - // - // foreach (var expenses in _operating_expenses.data) - // { - // ws.Cell(row, 1).Value = "'"+expenses.no; - // ws.Cell(row, 2).Value = expenses.expenditure_budget; - // ws.Cell(row, 3).Value = expenses.amount; - // ws.Cell(row, 4).Value = expenses.clarification_summary; - // - // ws.Range(ws.Cell(row, 1), ws.Cell(row, 4)).Style.Font.FontName = - // "TH SarabunPSK"; - // ws.Range(ws.Cell(row, 1), ws.Cell(row, 4)).Style.Font.FontSize = 14; - // ws.Range(ws.Cell(row, 1), ws.Cell(row, 4)).Style.Alignment.WrapText = true; - // ws.Range(ws.Cell(row, 1), ws.Cell(row, 4)).Style.Alignment.Vertical = - // XLAlignmentVerticalValues.Center; - // ws.Range(ws.Cell(row, 1), ws.Cell(row, 4)).Style.Border.OutsideBorder = XLBorderStyleValues.Thin; - // ws.Range(ws.Cell(row, 1), ws.Cell(row, 4)).Style.Border.RightBorder = XLBorderStyleValues.Thin; - // ws.Cell(row, 1).Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center; - // ws.Cell(row, 2).Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Left; - // ws.Cell(row, 3).Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Right; - // ws.Cell(row, 4).Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Left; - // ws.Range(ws.Cell(5, 1), ws.Cell(5, 4)).Style.Font.Bold = true; - // ws.Range(ws.Cell(6, 1), ws.Cell(6, 4)).Style.Border.BottomBorder = XLBorderStyleValues.Double; - // ws.Range(ws.Cell(6, 1), ws.Cell(6, 4)).Style.Font.Bold = true; - // //ws.Cell(row, 3).Style.NumberFormat.NumberFormatId = 2; - // //ws.Cell(row, 3).DataType = XLDataType.Number; - // //ws.Cell(row,3).SetDataType(XLDataType.Number); - // ws.Cell(row,3).Style.NumberFormat.SetFormat("#,#"); - // - // row++; - // } - // } - // using (var stream = new MemoryStream()) - // { - // workbook.SaveAs(stream); - // var content = stream.ToArray(); - // string date = DateTime.Now.ToString("yyyyMMddHHmmss"); - // return File( - // content, - // "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", - // "operatingexpenses_" + date + ".xlsx"); - // } - //} - //} } -} \ No newline at end of file +}