feiyu02
2022-07-20 39e208b6b0482a25c77e53590087c02d9d937563
src/main/kotlin/cn/flightfeather/supervision/common/utils/ExcelUtil.kt
@@ -2,11 +2,11 @@
import org.apache.poi.hssf.usermodel.HSSFWorkbook
import org.apache.poi.ss.util.CellRangeAddress
import java.io.File
import java.io.OutputStream
import java.time.LocalDate
import java.util.*
import kotlin.math.max
/**
 * @author riku
@@ -18,25 +18,27 @@
        var text: String,
        var rowSpan: Int = 1,
        var colSpan: Int = 1,
        var fontColor: Short? = null
        var fontColor: Short? = null,
        var isPercent:Boolean = false
    )
    /**
     * 自动处理行合并数据
     */
    fun write(heads: List<Array<String>>, contents: List<Array<Any>>, workbook: HSSFWorkbook, sheetName: String = "sheet1") {
    fun write(heads: List<Array<Any>>, contents: MutableList<Array<Any>>, workbook: HSSFWorkbook, sheetName: String = "sheet1") {
        val sheet = workbook.createSheet(sheetName)
        var rowIndex = 0
        heads.forEach {
            val rows = sheet.createRow(rowIndex)
            for (i in it.indices) {
                rows.createCell(i).setCellValue(it[i])
            }
            rowIndex++
        }
//        heads.forEach {
//            val rows = sheet.createRow(rowIndex)
//            for (i in it.indices) {
//                rows.createCell(i).setCellValue(it[i])
//            }
//            rowIndex++
//        }
        contents.addAll(0, heads)
        contents.forEach {
            val maxRow = getMaxRows(it)
@@ -87,22 +89,36 @@
                when (c) {
                    is MyCell -> {
                        rows.createCell(col).apply {
                            c.fontColor?.let {fC ->
                                val font = workbook.createFont()
                            if (c.isPercent) {
                                val cellStyle = workbook.createCellStyle()
                                font.color = fC
                                cellStyle.setFont(font)
                                val format = workbook.createDataFormat()
                                cellStyle.dataFormat = format.getFormat("0.0%")
                                setCellStyle(cellStyle)
                                val v = c.text.toDoubleOrNull()
                                if (v != null) {
                                    setCellValue(v)
                                }
                            } else {
                                c.fontColor?.let {fC ->
                                    val font = workbook.createFont()
                                    val cellStyle = workbook.createCellStyle()
                                    font.color = fC
                                    cellStyle.setFont(font)
                                    setCellStyle(cellStyle)
                                }
                                setCellValue(c.text)
                            }
                            setCellValue(c.text)
                        }
                        println("write1-1: ${c.text};($rowIndex, ${col})")
                    }
                    is String -> {
                        rows.createCell(col).setCellValue(c)
                        println("write1-2: ${c};($rowIndex, ${col})")
                        if (c.isNotBlank()) {
                            rows.createCell(col).setCellValue(c)
                            println("write1-2: ${c};($rowIndex, ${col})")
                        }
                    }
                    is Int -> rows.createCell(col).setCellValue(c.toDouble())
                    is Double -> rows.createCell(col).setCellValue(c)
                    is Boolean -> rows.createCell(col).setCellValue(c)
                    is Date -> rows.createCell(col).setCellValue(c)
@@ -146,13 +162,37 @@
                        when (c) {
                            is MyCell -> {
                                rows.createCell(map.key).setCellValue(c.text)
                                rows.createCell(col).apply {
                                    if (c.isPercent) {
                                        val cellStyle = workbook.createCellStyle()
                                        val format = workbook.createDataFormat()
                                        cellStyle.dataFormat = format.getFormat("0.0%")
                                        setCellStyle(cellStyle)
                                        val v = c.text.toDoubleOrNull()
                                        if (v != null) {
                                            setCellValue(v)
                                        }
                                    } else {
                                        c.fontColor?.let {fC ->
                                            val font = workbook.createFont()
                                            val cellStyle = workbook.createCellStyle()
                                            font.color = fC
                                            cellStyle.setFont(font)
                                            setCellStyle(cellStyle)
                                        }
                                        setCellValue(c.text)
                                    }
                                }
                                println("write2-1: ${c.text};($_rowIndex, ${map.key})")
                            }
                            is String -> {
                                rows.createCell(map.key).setCellValue(c)
                                println("write2-2: ${c};($_rowIndex, ${map.key})")
                                if (c.isNotBlank()) {
                                    rows.createCell(map.key).setCellValue(c)
                                    println("write2-2: ${c};($_rowIndex, ${map.key})")
                                }
                            }
                            is Int -> rows.createCell(map.key).setCellValue(c.toDouble())
                            is Double -> rows.createCell(map.key).setCellValue(c)
                            is Boolean -> rows.createCell(map.key).setCellValue(c)
                            is Date -> rows.createCell(map.key).setCellValue(c)
@@ -174,102 +214,16 @@
    /**
     * 自动处理行合并数据
     */
    fun write2(out: OutputStream, heads: List<String>, contents: List<Array<Any>>): String {
    fun write2(out: OutputStream, heads: List<Array<Any>>, contents: MutableList<Array<Any>>, sheetName: String = "sheet1") {
        val workbook = HSSFWorkbook()
        val sheet = workbook.createSheet("sheet1")
        write(heads, contents, workbook, sheetName)
        var rowIndex = 0
        if (heads.isNotEmpty()) {
            val rows = sheet.createRow(rowIndex)
            for (i in 0 until heads.size) {
                rows.createCell(i).setCellValue(heads[i])
            }
            rowIndex++
        }
        contents.forEach {
            val maxRow = getMaxRows(it)
            var rows = sheet.createRow(rowIndex)
            val arrayMap = mutableMapOf<Int, Array<*>>()
            for (i in it.indices) {
                val cell = it[i]
                var rowspan = maxRow//合并的行的跨度
                val c =
                        if (cell is Array<*>) {
                            //当数据为数组时,需要根据最大行数重新计算该单元格的行跨度
                            arrayMap[i] = cell
                            rowspan = maxRow / if(cell.size==0) 1 else cell.size
                            if (rowspan > 1) {
                                sheet.addMergedRegion(CellRangeAddress(rowIndex, rowIndex + rowspan - 1, i, i))
                            }
                            if (cell.isEmpty()) {
                                ""
                            } else {
                                cell[0]
                            }
                        } else {
                            //当数据不是数组时,需要按最大行数合并单元格
                            if (rowspan > 1) {
                                sheet.addMergedRegion(CellRangeAddress(rowIndex, rowIndex + rowspan - 1, i, i))
                            }
                            cell
                        }
                when (c) {
                    is String -> rows.createCell(i).setCellValue(c)
                    is Double -> rows.createCell(i).setCellValue(c)
                    is Boolean -> rows.createCell(i).setCellValue(c)
                    is Date -> rows.createCell(i).setCellValue(c)
                    is Calendar -> rows.createCell(i).setCellValue(c)
                    is LocalDate -> rows.createCell(i).setCellValue(c)
                }
            }
            for (i in 1 until maxRow) {
                rowIndex++
                rows = sheet.createRow(rowIndex)
                arrayMap.forEach {map ->
                    val array = map.value
                    if (i < array.size) {
                        val rowspan = maxRow / array.size
                        if (rowspan > 1) {
                            sheet.addMergedRegion(CellRangeAddress(rowIndex, rowIndex + rowspan - 1, i, i))
                        }
                        val c = array[i]
                        when (c) {
                            is String -> rows.createCell(map.key).setCellValue(c)
                            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++
        }
        val fileName = "${DateUtil().DateToString(Date(), "yyyy-MM-dd hh:mm:ss")}.xls"
        val filePath = "${Constant.DEFAULT_FILE_PATH}/files/$fileName"
        val xlsFile = File(filePath)
        if (!xlsFile.parentFile.exists()) {
            xlsFile.parentFile.mkdirs()
        }
//        val xlsStream = FileOutputStream(xlsFile)
        workbook.write(out)
        workbook.close()
        out.flush()
        out.close()
        return fileName
    }
    private fun getMaxRows(rowArray: Array<Any>): Int {