quarkus导入导出Excel文件,并使用中文文件名

 ExcelExportDto为数据返回的类

class ExcelExportDto {

    var couponCode: String? = null

    var batchName: String? = null

    var batchDescription: String? = null

    var code: String? = null
}

 依赖:

    // https://mvnrepository.com/artifact/org.apache.poi/poi
    implementation("org.apache.poi:poi:5.2.2")
    implementation("org.apache.poi:poi-ooxml:5.2.2")

自定义Excel工具:

import org.apache.poi.hssf.usermodel.HSSFCell
import org.apache.poi.hssf.usermodel.HSSFWorkbook
import org.apache.poi.ss.usermodel.Font
import org.apache.poi.ss.usermodel.HorizontalAlignment

/**
 * @Description :
 * @Author xiaomh
 * @date 2023/1/10 15:01
 */
class ExlUtils {
    fun getHSSFWorkbook(
        sheetName: String?,
        title: Array<String>,
        values: Array<Array<String?>>,
        workbook: HSSFWorkbook?
    ): HSSFWorkbook {
        // 创建一个HSSFWorkbook,对应一个Excel文件
        var workbook = workbook
        if (workbook == null) {
            workbook = HSSFWorkbook()
        }
        // 在workbook中添加一个sheet,对应Excel文件中的sheet
        val sheet = workbook.createSheet(sheetName)

        val font: Font = workbook.createFont()
//        font.fontHeightInPoints = 10.toShort()
        font.bold = true
        // 在sheet中添加表头第0行
        var row = sheet.createRow(0)
        // 创建单元格,并设置值表头 设置表头居中
        val cellStyle = workbook.createCellStyle()
        cellStyle.alignment = HorizontalAlignment.CENTER
        cellStyle.setFont(font)
        // 声明列对象
        var cell: HSSFCell? = null
        // 创建标题
        for (i in title.indices) {
            cell = row.createCell(i)
            cell.setCellValue(title[i])
            cell.setCellStyle(cellStyle)
        }
        // 创建内容
        for (i in values.indices) {
            row = sheet.createRow(i + 1)
            when (i) {
                0 -> sheet.setColumnWidth(i, pixelWidth(100).toInt())
                1 -> sheet.setColumnWidth(i, pixelWidth(100).toInt())
                2 -> sheet.setColumnWidth(i, pixelWidth(150).toInt())
                3 -> sheet.setColumnWidth(i, pixelWidth(400).toInt())
            }
            for (j in 0 until values[i].size) {
                // 将内容按顺序赋给对应的列对象
                row.createCell(j).setCellValue(values[i][j])
            }
        }
        return workbook
    }

    private fun pixelWidth(pxs: Int): Int {
        var width = (EXCEL_COLUMN_WIDTH_FACTOR * (pxs / UNIT_OFFSET_LENGTH))
        width += UNIT_OFFSET_MAP[pxs % UNIT_OFFSET_LENGTH]
        return width
    }

    companion object {
        const val EXCEL_COLUMN_WIDTH_FACTOR: Short = 256
        const val UNIT_OFFSET_LENGTH = 7
        val UNIT_OFFSET_MAP = intArrayOf(0, 36, 73, 109, 146, 182, 219)

    }
}

导出:

    @GET
    @Operation(summary = "导出excel表格", description = "导出excel表格")
    @Path("/coupon/export/excel/{couponReleaseId}")
//    @Produces("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
//    @Produces("application/vnd.ms-excel;charset=utf-8")
    @Authenticated
    fun exportInstanceExcel(@PathParam("couponReleaseId") couponReleaseId: UUID): Response {

        val fileContent= excelService.exportInstanceExcel(couponReleaseId)
        val dateTime = DateTimeFormatter.ofPattern("yyyyMMddHHmmss").format(LocalDateTime.now())
        val filename =  URLEncoder.encode("优惠码$dateTime.xls", "UTF-8")
        return Response.ok(fileContent)
            .header("Access-Control-Expose-Headers", "Content-Disposition")
            .header(HttpHeaders.CONTENT_TYPE, "application/vnd.ms-excel;charset=utf-8")
            //必须要加这一行,不然前端无法获取
            .header(HttpHeaders.CONTENT_DISPOSITION, String.format("attachment; filename=%s", filename))
            .build()
    }

    fun exportInstanceExcel( couponReleaseId: UUID): ByteArray {
        // Excel标题
        val title = arrayOf("优惠卷编号", "Batch Name", "Batch Description", "优惠码")
        // sheet名
        val sheetName = "优惠码"
        // 将数据放到数组中
        val instancePos: List<CouponInstance> = couponInstanceRepository.findByCouponReleaseId(couponReleaseId)
        val couponCode = instancePos[0].couponRelease?.coupon?.couponCode
        val batchName = instancePos[0].couponRelease?.name
        val batchDescription = instancePos[0].couponRelease?.description
        val instanceVos: List<ExcelExportDto> = instancePos.stream()
            .map { instance ->
                val excelExportDto = ExcelExportDto()
                excelExportDto.couponCode = couponCode
                excelExportDto.batchName = batchName
                excelExportDto.batchDescription = batchDescription
                excelExportDto.code = instance.code
                excelExportDto
            }
            .collect(Collectors.toList())
        val content = Array(instanceVos.size) {
            arrayOfNulls<String>(
                title.size
            )
        }
        for (i in instanceVos.indices) {
            val instanceVo: ExcelExportDto = instanceVos[i]
            content[i][0] = instanceVo.couponCode
            content[i][1] = instanceVo.batchName
            content[i][2] = instanceVo.batchDescription
            content[i][3] = instanceVo.code
        }
        // 导出Excel
        try {
            val exlUtils = ExlUtils()
            val hssfWorkbook = exlUtils.getHSSFWorkbook(sheetName, title, content, null)
            val outputStream: ByteArrayOutputStream = ByteArrayOutputStream()
            hssfWorkbook.write(outputStream)
            hssfWorkbook.close()
//            outputStream.flush()
            outputStream.close()
            return outputStream.toByteArray()
        } catch (e: Exception) {
            e.printStackTrace()
        }

        throw ApplicationException(ErrorCode.UNKNOWN_ERROR)
    }

 效果

导入:

    @POST
    @Path("/coupon/import/excel")
    @Consumes(MediaType.MULTIPART_FORM_DATA)
    @Authenticated
    fun importInstanceExcel(@MultipartForm formData: FileUploadFormData){
        excelService.readExcel(formData.file?.uploadedFile()?.toFile())
    }


@Throws(FileNotFoundException::class, IOException::class)
    fun readExcel(file: File?): List<Any>? {
//        val workbook = HSSFWorkbook(file?.let { FileInputStream(it) })
        val workbook = XSSFWorkbook(file?.let { FileInputStream(it) })
        //获取工作表,既可以根据工作表的顺序获取,也可以根据工作表的名称获取
        val sheet = workbook.getSheetAt(0)
        //设置单元格类型,不设置有些number数据会报错
        val lastRowNum = sheet.lastRowNum
        println(lastRowNum)
        for (i in 1..lastRowNum) {
            //根据行号获取行对象
            val row = sheet.getRow(i)
            val lastCellNum = row.lastCellNum
            for (j in 0 until lastCellNum) {
                val formatter = DataFormatter()
                val value = formatter.formatCellValue(row.getCell(j))
                print("$value  ")
            }
            println()
        }
        workbook.close()
        return null
    }

记录:org.apache.commons:commons-csv导出csv

依赖:

    implementation("org.apache.commons:commons-csv:1.10.0")

导出:

    @GET
    @Operation(summary = "导出scv表格", description = "导出scv表格")
    @Path("/coupon/export/csv/test")
//    @Produces("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
//    @Produces("application/vnd.ms-excel;charset=utf-8")
//    @Authenticated
    @Produces(MediaType.APPLICATION_OCTET_STREAM)
    fun export(): Response {
        val csvFile = excelService.exportInstanceCsv()
        val filename = URLEncoder.encode("优惠码${LocalDateTime.now()}.csv", "UTF-8")
        return Response.ok(csvFile)
            .header("Access-Control-Expose-Headers", "Content-Disposition")
            .header(HttpHeaders.CONTENT_TYPE, "application/vnd.ms-csv;charset=utf-8")
            .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=$filename")
            .build()
    }


    fun exportInstanceCsv(): ByteArray? {
        val instanceVos: MutableList<ExcelExportDto> = mutableListOf()
        instanceVos.add(ExcelExportDto().apply {
            this.couponCode = "TC001"
            this.batchName = "TEST001"
            this.batchDescription = "TEST001"
            this.code = "HAPPY001"
        })
        instanceVos.add(ExcelExportDto().apply {
            this.couponCode = "TC002"
            this.batchName = "TEST002"
            this.batchDescription = "TEST002"
            this.code = "HAPPY002"
        })
        val outputStream: ByteArrayOutputStream = ByteArrayOutputStream()
        val csvPrinter = CSVPrinter(
            OutputStreamWriter(outputStream),
            CSVFormat.DEFAULT.withHeader(
                "优惠卷编号", "Batch Name", "Batch Description", "优惠码"
            )
        )
        for (instanceVo in instanceVos) {
            csvPrinter.printRecord(
                instanceVo.couponCode,
                instanceVo.batchName,
                instanceVo.batchDescription,
                instanceVo.code
            )
        }
        csvPrinter.flush()
        csvPrinter.close()
        outputStream.close()

        return outputStream.toByteArray()
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值