官方网站

https://easyexcel.opensource.alibaba.com/docs/current/quickstart/read#最简单的读的excel示例

java代码:

package org.example.easyExc.controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.example.easyExc.entity.AsyncReq;
import org.example.easyExc.service.IAsyncReqService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * @Author lzg
 * @Create 2024/11/13 13:41
 * Description:
 * @Version 1.0
 */
@Slf4j
@ResponseBody
@Controller
public class EasyExcelController {

    @Autowired
    IAsyncReqService iAsyncReqService;


    @GetMapping("down/{count}")
    public void downExcel(HttpServletResponse response, @PathVariable("count") Integer count) throws InterruptedException, IOException {
        // 这里注意 有同学反应使用swagger 会导致各种问题,请直接用浏览器或者用postman
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode("测试211", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        List<AsyncReq> itemData = data(count);
        int skipIdx = 10000;
        long startTime = System.currentTimeMillis();
        // 这里 指定文件
        try (ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream(), AsyncReq.class).build()) {
            // 去调用写入,这里我调用了五次,实际使用时根据数据库分页的总的页数来。这里最终会写到5个sheet里面
            for (int i = 0; i < 10; i++) {
                // 每次都要创建writeSheet 这里注意必须指定sheetNo 而且sheetName必须不一样
                WriteSheet writeSheet = EasyExcel.writerSheet(i, "模板" + i).build();
                // 分页去数据库查询数据 这里可以去数据库查询每一页的数据
                excelWriter.write(itemData, writeSheet);
            }
        }

        System.out.println(System.currentTimeMillis() - startTime);

        /**
         *
         * 10000
         * 50000
         * 100000 2.578
         * 500000 13.148
         * 1000000 28.511 10万条数据一个sheet,打开13秒
         */
    }

    /**
     * 文件下载(失败了会返回一个有部分数据的Excel)
     * <p>
     * 1. 创建excel对应的实体对象 参照{@link AsyncReq}
     * <p>
     * 2. 设置返回的 参数
     * <p>
     * 3. 直接写,这里注意,finish的时候会自动关闭OutputStream,当然你外面再关闭流问题不大
     */
    @GetMapping("/download/{count}")
    public void download(HttpServletResponse response, @PathVariable("count") Integer count) throws IOException {
        // 这里注意 有同学反应使用swagger 会导致各种问题,请直接用浏览器或者用postman
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode("测试", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        List<AsyncReq> itemData = data(count);
        long startTime = System.currentTimeMillis();
        EasyExcel.write(response.getOutputStream(), AsyncReq.class).sheet("模板985").doWrite(itemData);
        System.out.println(System.currentTimeMillis() - startTime);


        /**
         * 10000 1.571
         * 50000 2.954
         * 100000 2.803
         * 500000 12.924
         * 1000000 26.340 100万条数据一个sheet,打开14秒
         *
         */
    }

    private Collection<AsyncReq> data(int start, int end) {
//        QueryChainWrapper<AsyncReq> query = iAsyncReqService.query();
        QueryWrapper<AsyncReq> query = new QueryWrapper<>();
        query.last("limit " + start + "," + end);
        List<AsyncReq> list = iAsyncReqService.list(query);
        log.info("db数量:{}", list.size());
        return list;
    }

    private List<AsyncReq> data(int count) {
        LocalDateTime now = LocalDateTime.now();
        //('234324324', 'mcpdng', 'async_type', 'routing_key', 'exchange', 'org.example.easyExc.entity.AsyncReq', '{}', 'init', '1', '1', '1', '{}', '2024-11-13 13:56:01','2024-11-13 13:56:01', '0');
        AsyncReq asyncReq = new AsyncReq().setAsyncId("121233").setAsyncType("async_type").setRoutingKey("routing_key")
                .setExchange("exchange")
                .setRoutingKey("routing_key")
                .setParamClassName("org.example.easyExc.entity.AsyncReq")
                .setParamJsonDetail("{}")
                .setExecStatus("1")
                .setUpdateTime(now)
                .setCreateTime(now)
                .setExecCount(1)
                .setSendCount(1)
                .setExtInfo("{}");
        List<AsyncReq> list = new ArrayList<>(count);
        for (int i = 0; i < count; i++) {
            list.add(asyncReq);
        }
        log.info("db数量:{}", list.size());
        return list;
    }

//    /**
//     * 文件上传
//     * <p>1. 创建excel对应的实体对象 参照{@link UploadData}
//     * <p>2. 由于默认一行行的读取excel,所以需要创建excel一行一行的回调监听器,参照{@link UploadDataListener}
//     * <p>3. 直接读即可
//     */
//    @PostMapping("upload")
//    @ResponseBody
//    public String upload(MultipartFile file) throws IOException {
//        EasyExcel.read(file.getInputStream(), AsyncReq.class, new UploadDataListener(uploadDAO)).sheet().doRead();
//        return "success";
//    }
}

小结:

使用了easyexcl 在排除了db的耗时之后, 多sheet页(10个sheet页)和单sheet页, 插入1百万(26s)/50万(12s)/10万(2s)/10万以下(2s)条数据的时间很相似; 几乎无差别, 影响速度的往往是db或是网络
百万条数据下(14s), 多sheet页(10页)和单sheet页, 在打开速度上很相似; 几乎无差别

easyexcl不允许多线程操作多个sheet页;他本身在插入数据表时已经用了多线程,如果多个sheet页再同时开可能会出问题;
可能也是这个原因导致多sheet页下速度没差别
posted on 2024-11-13 16:51  幂次方  阅读(5)  评论(0编辑  收藏  举报