riku
2021-07-12 d978297ae85b2d7453054e616bbbe87bfabe9cbe
src/main/kotlin/com/flightfeather/uav/common/utils/ExcelUtil.kt
@@ -12,9 +12,13 @@
 */
object ExcelUtil {
    private const val isLog = false
    class MyCell(
            var text: String,
            var rowSpan: Int = 1
            var rowSpan: Int = 1,
            var colSpan: Int = 1,
            var fontColor: Short? = null
    )
    /**
@@ -56,7 +60,7 @@
                                rowspan = c.rowSpan
                            }
                            if (rowspan > 1) {
                                println("合并1-1:$rowIndex;${rowIndex + rowspan - 1};$i")
                                log("合并1-1:$rowIndex;${rowIndex + rowspan - 1};$i")
                                sheet.addMergedRegion(CellRangeAddress(rowIndex, rowIndex + rowspan - 1, i, i))
                            }
                            if (cell.isEmpty()) {
@@ -67,7 +71,7 @@
                        } else {
                            //当数据不是数组时,需要按最大行数合并单元格
                            if (rowspan > 1) {
                                println("合并1-2:$rowIndex;${rowIndex + rowspan - 1};$i")
                                log("合并1-2:$rowIndex;${rowIndex + rowspan - 1};$i")
                                sheet.addMergedRegion(CellRangeAddress(rowIndex, rowIndex + rowspan - 1, i, i))
                            }
                            cell
@@ -75,11 +79,11 @@
                when (c) {
                    is MyCell -> {
                        rows.createCell(i).setCellValue(c.text)
                        println("write1-1: ${c.text};($rowIndex, ${i})")
                        log("write1-1: ${c.text};($rowIndex, ${i})")
                    }
                    is String -> {
                        rows.createCell(i).setCellValue(c)
                        println("write1-2: ${c};($rowIndex, ${i})")
                        log("write1-2: ${c};($rowIndex, ${i})")
                    }
                    is Double -> rows.createCell(i).setCellValue(c)
                    is Boolean -> rows.createCell(i).setCellValue(c)
@@ -114,18 +118,170 @@
                            rows = sheet.getRow(_rowIndex) ?: sheet.createRow(_rowIndex)
                        }
                        if (rowspan > 1) {
                            println("合并2:${index};${index + rowspan - 1};$i")
                            log("合并2:${index};${index + rowspan - 1};$i")
                            sheet.addMergedRegion(CellRangeAddress(index, index + rowspan - 1, i, i))
                        }
                        when (c) {
                            is MyCell -> {
                                rows.createCell(map.key).setCellValue(c.text)
                                println("write2-1: ${c.text};($_rowIndex, ${map.key})")
                                log("write2-1: ${c.text};($_rowIndex, ${map.key})")
                            }
                            is String -> {
                                rows.createCell(map.key).setCellValue(c)
                                println("write2-2: ${c};($_rowIndex, ${map.key})")
                                log("write2-2: ${c};($_rowIndex, ${map.key})")
                            }
                            is Double -> rows.createCell(map.key).setCellValue(c)
                            is Boolean -> rows.createCell(map.key).setCellValue(c)
                            is Date -> rows.createCell(map.key).setCellValue(c)
                            is Calendar -> rows.createCell(map.key).setCellValue(c)
                            is LocalDate -> rows.createCell(map.key).setCellValue(c)
                        }
                    }
                }
            }
            rowIndex++
        }
//        workbook.write(out)
//        workbook.close()
//        out.flush()
//        out.close()
    }
    /**
     * 自动处理行合并数据
     */
    fun write(heads: List<Array<String>>, contents: List<Array<Any>>, workbook: HSSFWorkbook, sheetName: String = "sheet1") {
        val sheet = workbook.createSheet(sheetName)
        println("sheet: $sheetName")
        var rowIndex = 0
        heads.forEach {
            val rows = sheet.createRow(rowIndex)
            for (i in it.indices) {
                rows.createCell(i).setCellValue(it[i])
            }
            rowIndex++
        }
        contents.forEach {
            val maxRow = getMaxRows(it)
            var rows = sheet.getRow(rowIndex) ?: sheet.createRow(rowIndex)
            val arrayMap = mutableMapOf<Int, Array<*>>()
            //列序号
            var col = 0
            for (i in it.indices) {
                val cell = it[i]
                var rowspan = maxRow//合并的行的跨度
                var colSpan = 1
                val c =
                    if (cell is Array<*>) {
                        //当数据为数组时,需要根据最大行数重新计算该单元格的行跨度
                        arrayMap[col] = cell
                        rowspan = maxRow / if (cell.size == 0) 1 else cell.size
                        val c = cell[0]
                        if (c is MyCell) {
                            rowspan = c.rowSpan
                            colSpan = c.colSpan
                        }
                        if (rowspan > 1 || colSpan > 1) {
                            log("合并1-1:$rowIndex;${rowIndex + rowspan - 1};$col")
                            sheet.addMergedRegion(CellRangeAddress(rowIndex, rowIndex + rowspan - 1, col, col + colSpan - 1))
                        }
                        if (cell.isEmpty()) {
                            ""
                        } else {
                            cell[0]
                        }
                    } else {
                        //当数据不是数组时,需要按最大行数合并单元格
                        if (cell is MyCell) {
                            rowspan = cell.rowSpan
                            colSpan = cell.colSpan
                        }
                        if (rowspan > 1 || colSpan > 1) {
                            log("合并1-2:$rowIndex;${rowIndex + rowspan - 1};$col")
                            sheet.addMergedRegion(CellRangeAddress(rowIndex, rowIndex + rowspan - 1, col, col + colSpan - 1))
                        }
                        cell
                    }
                when (c) {
                    is MyCell -> {
                        rows.createCell(col).apply {
                            c.fontColor?.let {fC ->
                                val font = workbook.createFont()
                                val cellStyle = workbook.createCellStyle()
                                font.color = fC
                                cellStyle.setFont(font)
                                setCellStyle(cellStyle)
                            }
                            setCellValue(c.text)
                        }
                        log("write1-1: ${c.text};($rowIndex, ${col})")
                    }
                    is String -> {
                        rows.createCell(col).setCellValue(c)
                        log("write1-2: ${c};($rowIndex, ${col})")
                    }
                    is Double -> rows.createCell(col).setCellValue(c)
                    is Int -> rows.createCell(col).setCellValue(c.toDouble())
                    is Boolean -> rows.createCell(col).setCellValue(c)
                    is Date -> rows.createCell(col).setCellValue(c)
                    is Calendar -> rows.createCell(col).setCellValue(c)
                    is LocalDate -> rows.createCell(col).setCellValue(c)
                }
                col += colSpan
            }
            for (i in 1 until maxRow) {
                rowIndex++
                arrayMap.forEach { map ->
                    rows = sheet.getRow(rowIndex) ?: sheet.createRow(rowIndex)
                    val array = map.value
                    if (i < array.size) {
//                        var rowspan = maxRow / array.size
                        var lastRowSpan = 1
                        var rowspan = 1
                        var colSpan = 1
                        val c = array[i]
                        if (c is MyCell) {
                            rowspan = c.rowSpan
                            colSpan = c.colSpan
                        }
                        val _c = array[i - 1]
                        if (_c is MyCell) {
                            lastRowSpan = _c.rowSpan
                        }
                        var _rowIndex = rowIndex
                        var index = rowIndex
                        if (lastRowSpan > 1) {
                            index = rowIndex + (i * lastRowSpan) - 1
                            _rowIndex = index
                            rows = sheet.getRow(_rowIndex) ?: sheet.createRow(_rowIndex)
                        }
                        if (rowspan > 1 || colSpan > 1) {
                            log("合并2:${index};${index + rowspan - 1};${map.key}")
                            sheet.addMergedRegion(CellRangeAddress(index, index + rowspan - 1, map.key, map.key + colSpan - 1))
                        }
                        when (c) {
                            is MyCell -> {
                                rows.createCell(map.key).setCellValue(c.text)
                                log("write2-1: ${c.text};($_rowIndex, ${map.key})")
                            }
                            is String -> {
                                rows.createCell(map.key).setCellValue(c)
                                log("write2-2: ${c};($_rowIndex, ${map.key})")
                            }
                            is Double -> rows.createCell(map.key).setCellValue(c)
                            is Boolean -> rows.createCell(map.key).setCellValue(c)
@@ -154,4 +310,10 @@
        }
        return maxRows
    }
    private fun log(log: String) {
        if (isLog) {
            println(log)
        }
    }
}