From 7d1e72db1f53ca1f1444bd126a6d01cc37f76f8d Mon Sep 17 00:00:00 2001 From: leoho2fi Date: Wed, 29 May 2024 16:20:14 +0800 Subject: [PATCH] add report comment --- .../modules/report/service/ReportService.kt | 114 ++++++++++-------- 1 file changed, 61 insertions(+), 53 deletions(-) diff --git a/src/main/java/com/ffii/tsms/modules/report/service/ReportService.kt b/src/main/java/com/ffii/tsms/modules/report/service/ReportService.kt index f49f190..afa1bc9 100644 --- a/src/main/java/com/ffii/tsms/modules/report/service/ReportService.kt +++ b/src/main/java/com/ffii/tsms/modules/report/service/ReportService.kt @@ -1404,50 +1404,54 @@ open class ReportService( return workbook } -//createLateStartReport -private fun createLateStartReport( - team: List, - customer: List, - templatePath: String, - teamId: Long, - clientId: Long, - lateStartData: List> -): Workbook { - val resource = ClassPathResource(templatePath) - val templateInputStream = resource.inputStream - val workbook: Workbook = XSSFWorkbook(templateInputStream) - val sheet = workbook.getSheetAt(0) - val evaluator: FormulaEvaluator = workbook.creationHelper.createFormulaEvaluator() - - // Apply standard and custom fonts - applyStandardAndCustomFonts(workbook, sheet) - - // Formatting the date in cell C2 - setDateInCellC2(workbook, sheet) - - setTeamAndClientIds(sheet, team, teamId, customer, clientId) - - // Set data and conditional formatting in columns - setDataAndConditionalFormatting(workbook, sheet, lateStartData, evaluator) - - // Auto-size columns to fit content - autoSizeColumns(sheet) - - return workbook -} + //createLateStartReport + private fun createLateStartReport( + team: List, + customer: List, + templatePath: String, + teamId: Long, + clientId: Long, + lateStartData: List> + ): Workbook { + val resource = ClassPathResource(templatePath) + val templateInputStream = resource.inputStream + val workbook: Workbook = XSSFWorkbook(templateInputStream) + val sheet = workbook.getSheetAt(0) + val evaluator: FormulaEvaluator = workbook.creationHelper.createFormulaEvaluator() + + // Apply standard and custom fonts + applyStandardAndCustomFonts(workbook, sheet) + + // Set the current date in cell C2 + setDateInCellC2(workbook, sheet) + + // Populate team and client information based on IDs + setTeamAndClientIds(sheet, team, teamId, customer, clientId) + // Process late start data, and apply data and conditional formatting to the sheet + setDataAndConditionalFormatting(workbook, sheet, lateStartData, evaluator) + + // Automatically adjust column widths to fit content + autoSizeColumns(sheet) + + return workbook + } + + // Configures standard and custom fonts within the workbook and applies specific styles to cells. private fun applyStandardAndCustomFonts(workbook: Workbook, sheet: Sheet) { + // Create and configure a bold Times New Roman font for general use val timesNewRoman = workbook.createFont().apply { fontName = "Times New Roman" fontHeightInPoints = 12 bold = true } + // Create and configure a larger, bold Times New Roman font for prominent headers val timesNewRomanLarge = workbook.createFont().apply { fontName = "Times New Roman" fontHeightInPoints = 16 bold = true } - // Apply custom font size for A1 + // Apply the larger custom font size to cell A1 for header emphasis val rowA1 = sheet.getRow(0) ?: sheet.createRow(0) val cellA1 = rowA1.getCell(0) ?: rowA1.createCell(0) val cellStyleA1 = workbook.createCellStyle().apply { @@ -1455,7 +1459,8 @@ private fun createLateStartReport( setFont(timesNewRomanLarge) } cellA1.cellStyle = cellStyleA1 - // Apply styles from A2 to A4 (bold) + + // Apply standard bold font to cells A2 to A4 val boldCellStyle = workbook.createCellStyle().apply { setFont(timesNewRoman) } listOf(1, 2, 3).forEach { rowIndex -> val row = sheet.getRow(rowIndex) ?: sheet.createRow(rowIndex) @@ -1463,39 +1468,42 @@ private fun createLateStartReport( cell.cellStyle = boldCellStyle } - // Apply styles from A6 to J6 (bold, bottom border, center alignment) + // Apply a bold, bottom-bordered, center-aligned style to header cells from A6 to J6 val styleA6ToJ6 = workbook.createCellStyle().apply { setFont(timesNewRoman) // Use the standard bold font for consistency alignment = HorizontalAlignment.CENTER borderBottom = BorderStyle.THIN } - // Apply styleA6ToJ6 to cells A6 to J6 val rowA6 = sheet.getRow(5) ?: sheet.createRow(5) (0..9).forEach { colIndex -> val cell = rowA6.getCell(colIndex) ?: rowA6.createCell(colIndex) cell.cellStyle = styleA6ToJ6 } } + + // Sets the current data in the Excel sheet at cell C2 using a specified date format private fun setDateInCellC2(workbook: Workbook, sheet: Sheet) { + // Format the current date to "yyyy/MM/dd" and set it to cell C2 val formattedToday = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd")) val dateCell = sheet.getRow(1)?.getCell(2) ?: sheet.getRow(1).createCell(2) dateCell.setCellValue(formattedToday) } + // Populates the Excel sheet with late start data and applies conditional formatting based on criteria. private fun setDataAndConditionalFormatting( workbook: Workbook, sheet: Sheet, lateStartData: List>, evaluator: FormulaEvaluator ) { - var dataRowIndex = 6 // Starting from row 7 + var dataRowIndex = 6 // Start populating data from row index 7 lateStartData.forEachIndexed { index, data -> val row = sheet.getRow(dataRowIndex) ?: sheet.createRow(dataRowIndex) populateDataRow(workbook, sheet, row, data, index) dataRowIndex++ } - // Update conditional formatting to apply to the new range of column J + // Update and apply conditional formatting to highlight specific values in column J val sheetCF = sheet.sheetConditionalFormatting val rule1 = sheetCF.createConditionalFormattingRule("J7 < 60") val pattern1 = rule1.createPatternFormatting().apply { @@ -1510,34 +1518,37 @@ private fun createLateStartReport( val region = CellRangeAddress(dataRowIndex - lateStartData.size, dataRowIndex - 1, 9, 9) // Column J sheetCF.addConditionalFormatting(arrayOf(region), arrayOf(rule1, rule2)) } + + // Sets team and client IDs in the sheet to manage data visibility based on the selected team and client private fun setTeamAndClientIds(sheet: Sheet, team: List, teamId: Long, customer: List, clientId: Long) { - // Set the 'teamId' value in cell C3 + // Insert the team name or "All" if no specific team is selected in cell C3 val teamIdRow = sheet.getRow(2) ?: sheet.createRow(2) val teamIdCell = teamIdRow.getCell(2) ?: teamIdRow.createCell(2) teamIdCell.setCellValue(if (teamId == 0L) "All" else team.getOrNull(0)?.name ?: "Unknown") - // Set the 'clientId' value in cell C4 + // Insert the client name or "All" if no specific client is selecred in cell C4 val clientIdRow = sheet.getRow(3) ?: sheet.createRow(3) val clientIdCell = clientIdRow.getCell(2) ?: clientIdRow.createCell(2) clientIdCell.setCellValue(if (clientId == 0L) "All" else customer.getOrNull(0)?.name ?: "Unknown") } - + // Populates a single row with data from a map and applies formatting and formulas private fun populateDataRow(workbook: Workbook, sheet: Sheet, row: Row, data: Map, index: Int) { val dateFormat = workbook.creationHelper.createDataFormat().getFormat("yyyy/MM/dd") - // Define the font for general use (if not already defined elsewhere) + // Define a font for general use throughout the row val generalFont = workbook.createFont().apply { fontName = "Times New Roman" - fontHeightInPoints = 12 // Standard size + fontHeightInPoints = 12 // Standard size is 11 } + // Create and apply a date format style for date cells val dateCellStyle = workbook.createCellStyle().apply { dataFormat = dateFormat - setFont(generalFont) // Apply the font here along with the date format + setFont(generalFont) // Maintain consistency in font usage } - // Create a style for center alignment for column G + // Style for center alignment, used in calcalated columns val centerAlignedStyle = workbook.createCellStyle().apply { alignment = HorizontalAlignment.CENTER - setFont(generalFont) // Maintain font consistency + setFont(generalFont) // Ensure font consistency } // Column A: Sequential ID @@ -1561,9 +1572,6 @@ private fun createLateStartReport( customerNameCell.setCellValue(data["customer_name"] as String) // // Column F: Project Plan Start Date -// val projectPlanStartCell = row.createCell(5) -// projectPlanStartCell.setCellValue(data["project_plan_start"].toString()) - // Parse the project start date and apply the date format val projectPlanStartCell = row.createCell(5) try { @@ -1583,7 +1591,7 @@ private fun createLateStartReport( val taskGroupNameCell = row.createCell(7) taskGroupNameCell.setCellValue(data["task_group_name"] as String) -// // Column I: Milestone End Date + // Column I: Milestone End Date val dateCell = row.createCell(8) // Milestone end date in column I try { val date = LocalDate.parse(data["milestone_end_date"].toString()) @@ -1593,7 +1601,7 @@ private fun createLateStartReport( } dateCell.cellStyle = dateCellStyle - // Get the current date and parse the milestone end date + // Calculate the days between current date and milestone end date, and display in column J val today = LocalDate.now() val endDate = LocalDate.parse(data["milestone_end_date"].toString(), DateTimeFormatter.ISO_LOCAL_DATE) val daysBetween = ChronoUnit.DAYS.between(today, endDate).toInt() // Calculate the difference in days @@ -1601,12 +1609,12 @@ private fun createLateStartReport( val daysDifferenceCellJ = row.createCell(9) daysDifferenceCellJ.setCellValue(daysBetween.toDouble()) // Set as double for consistency daysDifferenceCellJ.cellStyle = centerAlignedStyle - } + // Automatically adjusts the width if all columns in the sheet to fit their content optimally. private fun autoSizeColumns(sheet: Sheet) { - for (colIndex in 0..9) { - sheet.autoSizeColumn(colIndex) + for (colIndex in 0..9) { // Iterate through columns A to J + sheet.autoSizeColumn(colIndex) // Auto-size each column based on its content } }