|
|
@@ -1404,50 +1404,54 @@ open class ReportService( |
|
|
|
return workbook |
|
|
|
} |
|
|
|
|
|
|
|
//createLateStartReport |
|
|
|
private fun createLateStartReport( |
|
|
|
team: List<Team>, |
|
|
|
customer: List<Customer>, |
|
|
|
templatePath: String, |
|
|
|
teamId: Long, |
|
|
|
clientId: Long, |
|
|
|
lateStartData: List<Map<String, Any>> |
|
|
|
): 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<Team>, |
|
|
|
customer: List<Customer>, |
|
|
|
templatePath: String, |
|
|
|
teamId: Long, |
|
|
|
clientId: Long, |
|
|
|
lateStartData: List<Map<String, Any>> |
|
|
|
): 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<Map<String, Any>>, |
|
|
|
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<Team>, teamId: Long, customer: List<Customer>, 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<String, Any>, 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 |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|