feiyu02
2024-01-26 01eae19a4870033e879a3faa6749eece92926cab
src/main/kotlin/com/flightfeather/uav/common/utils/ExcelUtil.kt
@@ -1,7 +1,16 @@
package com.flightfeather.uav.common.utils
import org.apache.poi.hssf.usermodel.HSSFWorkbook
import com.flightfeather.uav.common.exception.ResponseErrorException
import org.apache.poi.ss.usermodel.Row
import org.apache.poi.ss.util.CellRangeAddress
import org.apache.poi.xssf.streaming.SXSSFWorkbook
import org.apache.poi.xssf.usermodel.XSSFRow
import org.apache.poi.xssf.usermodel.XSSFWorkbook
import org.jetbrains.kotlin.incremental.isJavaFile
import java.io.ByteArrayInputStream
import java.io.File
import java.io.FileInputStream
import java.io.InputStream
import java.time.LocalDate
import java.util.*
import kotlin.math.max
@@ -15,16 +24,44 @@
    private const val isLog = false
    class MyCell(
            var text: String,
            var rowSpan: Int = 1,
            var colSpan: Int = 1,
            var fontColor: Short? = null
        var text: String,
        var rowSpan: Int = 1,
        var colSpan: Int = 1,
        var fontColor: Short? = null,
    )
    /**
     * 读取文件
     * @param file 要读取的文件
     * @param headerCheck 文件首行检查回调
     * @param onRow 单行内容回调,从第二行开始
     */
    fun read(file: File, headerCheck: (header: XSSFRow) -> Boolean, onRow: (row: Row) -> Unit): Boolean {
        if (!file.exists() || !file.isFile) throw ResponseErrorException("it's not a normal file!")
        if (!file.extension.equals("xls", ignoreCase = true) || !file.extension.equals("xlsx", ignoreCase = true)) {
            throw ResponseErrorException("file's extension name should be xls or xlsx!")
        }
        return read(FileInputStream(file), headerCheck, onRow)
    }
    fun read(input: InputStream, headerCheck: (header: XSSFRow) -> Boolean, onRow: (row: Row) -> Unit): Boolean {
        val workbook = XSSFWorkbook(input)
        val sheet1 = workbook.getSheetAt(0)
        val header = sheet1.getRow(sheet1.topRow.toInt())
        return if (headerCheck(header)) {
            // 获取迭代器并去除第一行标题
            val iterator = sheet1.rowIterator().also { it.next() }
            iterator.forEach { onRow(it) }
            true
        } else {
            false
        }
    }
    /**
     * 自动处理行合并数据
     */
    fun write2(heads: List<String>, contents: List<Array<Any>>, workbook: HSSFWorkbook, sheetName:String) {
    fun write2(heads: List<String>, contents: List<Array<Any>>, workbook: SXSSFWorkbook, sheetName: String) {
        val sheet = workbook.createSheet(sheetName)
@@ -51,31 +88,31 @@
                var rowspan = maxRow//合并的行的跨度
                val c =
                        if (cell is Array<*>) {
                            //当数据为数组时,需要根据最大行数重新计算该单元格的行跨度
                            arrayMap[i] = cell
                            rowspan = maxRow / if (cell.size == 0) 1 else cell.size
                            val c = cell[0]
                            if (c is MyCell) {
                                rowspan = c.rowSpan
                            }
                            if (rowspan > 1) {
                                log("合并1-1:$rowIndex;${rowIndex + rowspan - 1};$i")
                                sheet.addMergedRegion(CellRangeAddress(rowIndex, rowIndex + rowspan - 1, i, i))
                            }
                            if (cell.isEmpty()) {
                                ""
                            } else {
                                cell[0]
                            }
                        } else {
                            //当数据不是数组时,需要按最大行数合并单元格
                            if (rowspan > 1) {
                                log("合并1-2:$rowIndex;${rowIndex + rowspan - 1};$i")
                                sheet.addMergedRegion(CellRangeAddress(rowIndex, rowIndex + rowspan - 1, i, i))
                            }
                            cell
                    if (cell is Array<*>) {
                        //当数据为数组时,需要根据最大行数重新计算该单元格的行跨度
                        arrayMap[i] = cell
                        rowspan = maxRow / if (cell.size == 0) 1 else cell.size
                        val c = cell[0]
                        if (c is MyCell) {
                            rowspan = c.rowSpan
                        }
                        if (rowspan > 1) {
                            log("合并1-1:$rowIndex;${rowIndex + rowspan - 1};$i")
                            sheet.addMergedRegion(CellRangeAddress(rowIndex, rowIndex + rowspan - 1, i, i))
                        }
                        if (cell.isEmpty()) {
                            ""
                        } else {
                            cell[0]
                        }
                    } else {
                        //当数据不是数组时,需要按最大行数合并单元格
                        if (rowspan > 1) {
                            log("合并1-2:$rowIndex;${rowIndex + rowspan - 1};$i")
                            sheet.addMergedRegion(CellRangeAddress(rowIndex, rowIndex + rowspan - 1, i, i))
                        }
                        cell
                    }
                when (c) {
                    is MyCell -> {
                        rows.createCell(i).setCellValue(c.text)
@@ -106,7 +143,7 @@
                        if (c is MyCell) {
                            rowspan = c.rowSpan
                        }
                        val _c = array[i-1]
                        val _c = array[i - 1]
                        if (_c is MyCell) {
                            lastRowSpan = _c.rowSpan
                        }
@@ -152,12 +189,18 @@
    /**
     * 自动处理行合并数据
     */
    fun write(heads: List<Array<String>>, contents: List<Array<Any>>, workbook: HSSFWorkbook, sheetName: String = "sheet1") {
    fun write(
        heads: List<Array<String>>,
        contents: List<Array<Any>>,
        workbook: SXSSFWorkbook,
        sheetName: String = "sheet1",
        row: Int = 0,
    ): Int {
        val sheet = workbook.createSheet(sheetName)
        println("sheet: $sheetName")
        val sheet = workbook.getSheet(sheetName) ?: workbook.createSheet(sheetName)
//        println("sheet: $sheetName")
        var rowIndex = 0
        var rowIndex = row
        heads.forEach {
            val rows = sheet.createRow(rowIndex)
@@ -194,7 +237,10 @@
                        }
                        if (rowspan > 1 || colSpan > 1) {
                            log("合并1-1:$rowIndex;${rowIndex + rowspan - 1};$col")
                            sheet.addMergedRegion(CellRangeAddress(rowIndex, rowIndex + rowspan - 1, col, col + colSpan - 1))
                            sheet.addMergedRegion(CellRangeAddress(rowIndex,
                                rowIndex + rowspan - 1,
                                col,
                                col + colSpan - 1))
                        }
                        if (cell.isEmpty()) {
                            ""
@@ -202,21 +248,24 @@
                            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))
                            sheet.addMergedRegion(CellRangeAddress(rowIndex,
                                rowIndex + rowspan - 1,
                                col,
                                col + colSpan - 1))
                        }
                        cell
                    }
                when (c) {
                    is MyCell -> {
                        rows.createCell(col).apply {
                            c.fontColor?.let {fC ->
                            c.fontColor?.let { fC ->
                                val font = workbook.createFont()
                                val cellStyle = workbook.createCellStyle()
@@ -271,7 +320,10 @@
                        }
                        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))
                            sheet.addMergedRegion(CellRangeAddress(index,
                                index + rowspan - 1,
                                map.key,
                                map.key + colSpan - 1))
                        }
                        when (c) {
@@ -299,6 +351,7 @@
//        workbook.close()
//        out.flush()
//        out.close()
        return rowIndex
    }
    private fun getMaxRows(rowArray: Array<Any>): Int {