EN · DE · RU · FR · ES

#1153: VacationExcelExporter.kt

projectforge-business/src/main/kotlin/org/projectforge/business/vacation/service/VacationExcelExporter.kt Kotlin class, projectforge-business/src/main/kotlin/org/projectforge/business/vacation/service/VacationExcelExporter.kt 389 lines · 331 code · 39 comments · 19 blank
Purpose: Source file: business/vacation/service/VacationExcelExporter.kt. VacationExcelExporter.kt is part of the ProjectForge open-source project management application.

Source (first 100 lines)

/////////////////////////////////////////////////////////////////////////////
//
// Project ProjectForge Community Edition
//         www.projectforge.org
//
// Copyright (C) 2001-2026 Micromata GmbH, Germany (www.micromata.com)
//
// ProjectForge is dual-licensed.
//
// This community edition is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as published
// by the Free Software Foundation; version 3 of the License.
//
// This community edition is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
// Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, see http://www.gnu.org/licenses/.
//
/////////////////////////////////////////////////////////////////////////////

package org.projectforge.business.vacation.service

import de.micromata.merlin.excel.ExcelRow
import de.micromata.merlin.excel.ExcelSheet
import de.micromata.merlin.excel.ExcelWorkbook
import mu.KotlinLogging
import org.apache.poi.ss.usermodel.BorderStyle
import org.apache.poi.ss.usermodel.HorizontalAlignment
import org.apache.poi.ss.usermodel.IndexedColors
import org.apache.poi.ss.util.CellRangeAddress
import org.projectforge.business.fibu.EmployeeDO
import org.projectforge.business.vacation.model.VacationDO
import org.projectforge.business.vacation.model.VacationStatus
import org.projectforge.excel.ExcelUtils
import org.projectforge.framework.configuration.ConfigXml
import org.projectforge.framework.i18n.translate
import org.projectforge.framework.persistence.user.api.ThreadLocalUserContext
import org.projectforge.framework.persistence.user.entities.PFUserDO
import org.projectforge.framework.time.DateHelper
import org.projectforge.framework.time.PFDay
import org.projectforge.framework.xmlstream.XmlHelper
import org.springframework.core.io.ByteArrayResource
import org.springframework.http.HttpHeaders
import org.springframework.http.ResponseEntity
import java.io.File
import java.time.LocalDate
import java.time.Month
import java.time.format.TextStyle
import java.util.*

private val log = KotlinLogging.logger {}

/**
 * Exports vacation entries of users.
 * @author K. Reinhard (k.reinhard@micromata.de)
 */
object VacationExcelExporter {
  private class Context(val workbook: ExcelWorkbook) {
    lateinit var currentSheet: ExcelSheet
      private set
    val monthSeparatorCols = mutableListOf<Int>()
    val monthSeparationStyle = ExcelUtils.createCellStyle(
      workbook,
      "monthSeparation",
      fillForegroundColor = IndexedColors.BLACK,
    )
    val boldFont = ExcelUtils.createFont(workbook, "bold", bold = true, heightInPoints = 18)
    val monthStyle =
      ExcelUtils.createCellStyle(workbook, "month", font = boldFont, alignment = HorizontalAlignment.CENTER)
    val standardStyle = ExcelUtils.createCellStyle(workbook, "standard", borderStyle = BorderStyle.THIN)
    val standardDayStyle = ExcelUtils.createCellStyle(
      workbook,
      "standardDay",
      alignment = HorizontalAlignment.CENTER,
      borderStyle = BorderStyle.THIN,
    )
    val holidayAndWeekendStyle = ExcelUtils.createCellStyle(
      workbook,
      "holidayWeekendDay",
      alignment = HorizontalAlignment.CENTER,
      fillForegroundColor = IndexedColors.TAN,
      borderStyle = BorderStyle.THIN,
    )
    val vacationStyle = ExcelUtils.createCellStyle(
      workbook,
      "vacationDay",
      fillForegroundColor = IndexedColors.GREEN,
      borderStyle = BorderStyle.THIN,
    )
    val unapprovedVacationStyle = ExcelUtils.createCellStyle(
      workbook,
      "unapprovedVacationDay",
      fillForegroundColor = IndexedColors.GREY_40_PERCENT,
      borderStyle = BorderStyle.THIN,
    )

    fun withSheet(sheet: ExcelSheet) {

Git History

868d6abb7 2025 -> 2026
78a38ca8f ExcelUtils.createFont and used by all font creating excel routines.
63081666f Source file headers: 2024-> 2025.
b6092df09 Copyright 2023 -> 2024
4a4c891d4 VacationExcelExporter: Autofilter added.

868d6abb7

2025 -> 2026
868d6abb75cd191a892911ac8e45058932cf9074
diff --git a/projectforge-business/src/main/kotlin/org/projectforge/business/vacation/service/VacationExcelExporter.kt b/projectforge-business/src/main/kotlin/org/projectforge/business/vacation/service/VacationExcelExporter.kt
index a245235c2..14fba9917 100644
--- a/projectforge-business/src/main/kotlin/org/projectforge/business/vacation/service/VacationExcelExporter.kt
+++ b/projectforge-business/src/main/kotlin/org/projectforge/business/vacation/service/VacationExcelExporter.kt
@@ -3,7 +3,7 @@
 // Project ProjectForge Community Edition
 //         www.projectforge.org
 //
-// Copyright (C) 2001-2025 Micromata GmbH, Germany (www.micromata.com)
+// Copyright (C) 2001-2026 Micromata GmbH, Germany (www.micromata.com)
 //
 // ProjectForge is dual-licensed.
 //

78a38ca8f

ExcelUtils.createFont and used by all font creating excel routines.
78a38ca8fe252bcfd1eddfc95318a6507f33bda2
diff --git a/projectforge-business/src/main/kotlin/org/projectforge/business/vacation/service/VacationExcelExporter.kt b/projectforge-business/src/main/kotlin/org/projectforge/business/vacation/service/VacationExcelExporter.kt
index 1ddbca545..a245235c2 100644
--- a/projectforge-business/src/main/kotlin/org/projectforge/business/vacation/service/VacationExcelExporter.kt
+++ b/projectforge-business/src/main/kotlin/org/projectforge/business/vacation/service/VacationExcelExporter.kt
@@ -67,7 +67,7 @@ object VacationExcelExporter {
       "monthSeparation",
       fillForegroundColor = IndexedColors.BLACK,
     )
-    val boldFont = workbook.createOrGetFont("bold", bold = true, heightInPoints = 18)
+    val boldFont = ExcelUtils.createFont(workbook, "bold", bold = true, heightInPoints = 18)
     val monthStyle =
       ExcelUtils.createCellStyle(workbook, "month", font = boldFont, alignment = HorizontalAlignment.CENTER)
     val standardStyle = ExcelUtils.createCellStyle(workbook, "standard", borderStyle = BorderStyle.THIN)

63081666f

Source file headers: 2024-> 2025.
63081666f620fb87315f01b817e560e0b2f6a33a
diff --git a/projectforge-business/src/main/kotlin/org/projectforge/business/vacation/service/VacationExcelExporter.kt b/projectforge-business/src/main/kotlin/org/projectforge/business/vacation/service/VacationExcelExporter.kt
index d103929d1..1ddbca545 100644
--- a/projectforge-business/src/main/kotlin/org/projectforge/business/vacation/service/VacationExcelExporter.kt
+++ b/projectforge-business/src/main/kotlin/org/projectforge/business/vacation/service/VacationExcelExporter.kt
@@ -3,7 +3,7 @@
 // Project ProjectForge Community Edition
 //         www.projectforge.org
 //
-// Copyright (C) 2001-2024 Micromata GmbH, Germany (www.micromata.com)
+// Copyright (C) 2001-2025 Micromata GmbH, Germany (www.micromata.com)
 //
 // ProjectForge is dual-licensed.
 //

b6092df09

Copyright 2023 -> 2024
b6092df0927c4a3b161e888445f31dcab57493f2
diff --git a/projectforge-business/src/main/kotlin/org/projectforge/business/vacation/service/VacationExcelExporter.kt b/projectforge-business/src/main/kotlin/org/projectforge/business/vacation/service/VacationExcelExporter.kt
index 8a3bef0a8..d103929d1 100644
--- a/projectforge-business/src/main/kotlin/org/projectforge/business/vacation/service/VacationExcelExporter.kt
+++ b/projectforge-business/src/main/kotlin/org/projectforge/business/vacation/service/VacationExcelExporter.kt
@@ -3,7 +3,7 @@
 // Project ProjectForge Community Edition
 //         www.projectforge.org
 //
-// Copyright (C) 2001-2023 Micromata GmbH, Germany (www.micromata.com)
+// Copyright (C) 2001-2024 Micromata GmbH, Germany (www.micromata.com)
 //
 // ProjectForge is dual-licensed.
 //

4a4c891d4

VacationExcelExporter: Autofilter added.
4a4c891d4a0be89b4b329545cd516a7b1c958dcf
diff --git a/projectforge-business/src/main/kotlin/org/projectforge/business/vacation/service/VacationExcelExporter.kt b/projectforge-business/src/main/kotlin/org/projectforge/business/vacation/service/VacationExcelExporter.kt
index 033c555a6..8a3bef0a8 100644
--- a/projectforge-business/src/main/kotlin/org/projectforge/business/vacation/service/VacationExcelExporter.kt
+++ b/projectforge-business/src/main/kotlin/org/projectforge/business/vacation/service/VacationExcelExporter.kt
@@ -30,6 +30,7 @@ import mu.KotlinLogging
 import org.apache.poi.ss.usermodel.BorderStyle
 import org.apache.poi.ss.usermodel.HorizontalAlignment
 import org.apache.poi.ss.usermodel.IndexedColors
+import org.apache.poi.ss.util.CellRangeAddress
 import org.projectforge.business.fibu.EmployeeDO
 import org.projectforge.business.vacation.model.VacationDO
 import org.projectforge.business.vacation.model.VacationStatus
@@ -141,13 +142,16 @@ object VacationExcelExporter {
     sheet.poiSheet.printSetup.landscape = true
     sheet.poiSheet.printSetup.fitWidth = 1.toShort()  // Doesn't work
     sheet.poiSheet.printSetup.fitHeight = 0.toShort() // Doesn't work
-    val monthRow = sheet.createRow()
+    val firstRow = sheet.createRow()
     val dateRow = sheet.createRow()
     val weekDayRow = sheet.createRow()
     var currentDate = startDate
     var columnIndex = 0
+    firstRow.getCell(columnIndex).setCellValue(translate("fibu.employees"))
     sheet.setColumnWidth(columnIndex, COL_WIDTH_USER) // Column of vacationers.
-    createMonthSeparationCells(context, ++columnIndex, dateRow, weekDayRow, monthRow)
+    firstRow.getCell(++columnIndex).setCellValue(translate("vacation"))
+    sheet.setColumnWidth(columnIndex, 500) // Column if employee has any vacation or not.
+    createMonthSeparationCells(context, ++columnIndex, dateRow, weekDayRow, firstRow)
     var paranoiaCounter = 0
     var firstDayOfMonthCol = columnIndex + 1
     val columnIndexMap = mutableMapOf<LocalDate, Int>()
@@ -167,14 +171,14 @@ object VacationExcelExporter {
         // New month started.
         val monthCell =
           sheet.setMergedRegion(
-            monthRow.rowNum,
-            monthRow.rowNum,
+            firstRow.rowNum,
+            firstRow.rowNum,
             firstDayOfMonthCol,
             columnIndex,
             getMonthString(currentDate.minusMonths(1)),
           )
         monthCell.setCellStyle(context.monthStyle)
-        createMonthSeparationCells(context, ++columnIndex, dateRow, weekDayRow, monthRow)
+        createMonthSeparationCells(context, ++columnIndex, dateRow, weekDayRow, firstRow)
         firstDayOfMonthCol = columnIndex + 1 // Store column for setMergedRegion of month name.
       }
     }
@@ -195,6 +199,7 @@ object VacationExcelExporter {
         }
         currentDate = currentDate.plusDays(1)
       }
+      var firstRowWritten = false
       entry.vacations.forEach { vacation ->
         val vacationStart = PFDay.fromOrNull(vacation.startDate)
         val vacationEnd = PFDay.fromOrNull(vacation.endDate)
@@ -208,6 +213,11 @@ object VacationExcelExporter {
           var current: PFDay = vacationStart