Java使用EasyExcel导出并上传到文件存储服务

前言

  • 针对数万以上数据量的导出,使用EasyExcel,提升导出速度,降低服务器的内存占用.
  • 导出时先上传至文件存储服务,再将文件地址返回给前端,避免浏览器直接处理文件流.

代码部分

pom文件

        <!--easyexcel-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>easyexcel</artifactId>
            <version>3.3.2</version>
        </dependency>

工具类

    /**
     * 导出Excel返回FileInputStream
     */
    public static FileInputStream exportExcelStream(Class<?> clazz, List<?> list) {
        try {
            // 临时目录 临时文件名
            String tmp = System.getProperty("java.io.tmpdir");
            String fileName = String.valueOf(new Date().getTime());
            File file = new File(tmp + fileName + ".xlsx");
            FileOutputStream fileOutputStream =  new FileOutputStream(file);
            ExcelWriter excelWriter = write(fileOutputStream)
                    .registerWriteHandler(new ExcelColumnWidthHandler())
                    .registerWriteHandler(new ExcelSheetWriteHandler())
                    .registerWriteHandler(new ExcelStyleHandler())
                    .build();
            WriteSheet writeSheet = writerSheet(0, fileName).head(clazz).build();
            excelWriter.write(list, writeSheet);
            excelWriter.finish();
            return new FileInputStream(file);
        } catch (Exception e) {
            throw new ServiceException("导出Excel异常");
        }
    }
    /**
     * 导出示例
     */
    @PostMapping("/exportBill")
    public Result exportBill() throws IOException {
        BillPageVo vo = new BillPageVo();
        vo.setCompanyName("");
        vo.setThirdBillNo("");
        vo.setCompanyCode("");
        vo.setBillNo("");
        vo.setGoodsName("");
        FileInputStream fileInputStream = ExcelUtil.exportExcelStream(BillPageVo.class, Collections.singletonList(vo));
        // 上传文件到文件存储服务OSS
        String url = ossUtil.upload("test/excel/" + "车辆运单导出.xlsx", fileInputStream);
        fileInputStream.close();
        return Result.success(url);
    }

easyexcel配置

/**
 * 根据表头设置列宽
 */
public class ExcelColumnWidthHandler extends AbstractColumnWidthStyleStrategy {

    @Override
    protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List<WriteCellData<?>> cellDataList, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
        if (Boolean.TRUE.equals(isHead)) {
            int columnWidth = cell.getStringCellValue().length();
            columnWidth = Math.max(columnWidth * 2, 18);
            if (columnWidth > 255) {
                columnWidth = 255;
            }
            writeSheetHolder.getSheet().setColumnWidth(cell.getColumnIndex(), columnWidth * 256);
        }
    }
}
/**
 * 设置单元格为文本格式
 */
public class ExcelSheetWriteHandler implements SheetWriteHandler {

    // 设置100列column
    private static final Integer COLUMN = 100;

    @Override
    public void beforeSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {

    }

    @Override
    public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
        for (int i = 0; i < COLUMN; i++) {
            // 设置为文本格式
            SXSSFSheet sxssfSheet = (SXSSFSheet) writeSheetHolder.getSheet();
            CellStyle cellStyle = writeWorkbookHolder.getCachedWorkbook().createCellStyle();
            // 49为文本格式
            cellStyle.setDataFormat((short) 49);
            // i为列,一整列设置为文本格式
            sxssfSheet.setDefaultColumnStyle(i, cellStyle);
        }
    }

}
/**
 * 自定义样式handler
 */
public class ExcelStyleHandler extends AbstractVerticalCellStyleStrategy {

    @Override
    protected WriteCellStyle contentCellStyle(Head head) {
        // 内容的策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        // 居中
        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        // 背景白色
        contentWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
        contentWriteCellStyle.setBorderLeft(BorderStyle.THIN);
        contentWriteCellStyle.setBorderTop(BorderStyle.THIN);
        contentWriteCellStyle.setBorderRight(BorderStyle.THIN);
        contentWriteCellStyle.setBorderBottom(BorderStyle.THIN);
        WriteFont contentWriteFont = new WriteFont();
        // 字体大小
        contentWriteFont.setFontHeightInPoints((short) 12);
        // 字体样式
        contentWriteFont.setFontName("等线");
        contentWriteCellStyle.setWriteFont(contentWriteFont);
        return contentWriteCellStyle;
    }
}
  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
使用 EasyExcel 导出复杂自定义表头,需要先定义一个类来描述表头的结构。这个类需要继承自 com.alibaba.excel.metadata.BaseRowModel 类,并且需要在类中定义一个 List<List<String>> 类型的变量来存储表头的内容。代码如下: ``` public class ComplexHeadData extends BaseRowModel { // 表头第一行内容 @ExcelProperty(value = {"表头1", "子头1", "子子头1"}, index = 0) private String head1; @ExcelProperty(value = {"表头1", "子头1", "子子头2"}, index = 1) private String head2; // 表头第二行内容 @ExcelProperty(value = {"表头1", "子头2", "子子头1"}, index = 2) private String head3; @ExcelProperty(value = {"表头1", "子头2", "子子头2"}, index = 3) private String head4; // 表头第三行内容 @ExcelProperty(value = {"表头2", "子头1", "子子头1"}, index = 4) private String head5; @ExcelProperty(value = {"表头2", "子头1", "子子头2"}, index = 5) private String head6; // 表头第四行内容 @ExcelProperty(value = {"表头2", "子头2", "子子头1"}, index = 6) private String head7; @ExcelProperty(value = {"表头2", "子头2", "子子头2"}, index = 7) private String head8; // 表头 private List<List<String>> head; public ComplexHeadData() { // 初始化表头结构 head = new ArrayList<>(); head.add(Arrays.asList("表头1", "表头1", "表头1", "表头1")); head.add(Arrays.asList("子头1", "子头1", "子头2", "子头2")); head.add(Arrays.asList("子子头1", "子子头2", "子子头1", "子子头2")); head.add(Arrays.asList("表头2", "表头2", "表头2", "表头2")); head.add(Arrays.asList("子头1", "子头1", "子头2", "子头2")); head.add(Arrays.asList("子子头1", "子子头2", "子子头1", "子子头2")); } public String getHead1() { return head1; } public void setHead1(String head1) { this.head1 = head1; } public String getHead2() { return head2; } public void setHead2(String head2) { this.head2 = head2; } public String getHead3() { return head3; } public void setHead3(String head3) { this.head3 = head3; } public String getHead4() { return head4; } public void setHead4(String head4) { this.head4 = head4; } public String getHead5() { return head5; } public void setHead5(String head5) { this.head5 = head5; } public String getHead6() { return head6; } public void setHead6(String head6) { this.head6 = head6; } public String getHead7() { return head7; } public void setHead7(String head7) { this.head7 = head7; } public String getHead8() { return head8; } public void setHead8(String head8) { this.head8 = head8; } public List<List<String>> getHead() { return head; } public void setHead(List<List<String>> head) { this.head = head; } } ``` 在定义好表头类之后,就可以使用 EasyExcel 提供的 ExcelWriter 类来进行数据导出。在 ExcelWriter 的构造函数中,需要传入一个 OutputStream 类型的参数,用于指定导出文件输出位置。然后,通过调用 ExcelWriter 的 write 方法,将数据写入到 Excel 文件中。代码如下: ``` // 定义表头数据 ComplexHeadData complexHeadData = new ComplexHeadData(); // 定义导出数据 List<List<Object>> data = new ArrayList<>(); data.add(Arrays.asList("数据1", "数据2", "数据3", "数据4", "数据5", "数据6", "数据7", "数据8")); data.add(Arrays.asList("数据1", "数据2", "数据3", "数据4", "数据5", "数据6", "数据7", "数据8")); // 创建 ExcelWriter 对象 ExcelWriter excelWriter = new ExcelWriter(outputStream, ExcelTypeEnum.XLSX); // 创建工作表对象 WriteSheet writeSheet = EasyExcel.writerSheet().build(); // 写入表头 excelWriter.write(complexHeadData.getHead(), writeSheet); // 写入数据 excelWriter.write(data, writeSheet); // 关闭 ExcelWriter 对象 excelWriter.finish(); ``` 在代码中,需要注意以下几点: 1. 在定义表头类时,需要使用 @ExcelProperty 注解来指定表头的内容和索引位置。 2. 在创建 ExcelWriter 对象时,需要指定输出的文件位置和文件类型。 3. 在创建工作表对象时,可以使用 EasyExcel 提供的 builder 模式来进行配置。 4. 在写入表头和数据时,需要使用 ExcelWriter 的 write 方法,并且需要将表头和数据分别写入两次。 5. 在写入完数据后,需要调用 ExcelWriter 的 finish 方法来关闭 ExcelWriter 对象。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

之一丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值