Java 实时显示处理进度条功能

发布于 2023-12-28 07:14:08 字数 3693 浏览 29 评论 0

整体思路:一个接口负责接收前端上传的文件,并创建线程处理该文件;另一个接口负责实时返回当前文件的处理进程(前端轮询)。

@RestController
public class TestController {

    private final static String EXCEL_2003_L = ".xls";    //2003- 版本的 excel
    private final static String EXCEL_2007_U = ".xlsx";   //2007+ 版本的 excel

    /**
     * 缓存处理线程
     */
    private final static Map<String, DealThread> threadMap = new HashMap<>();

    /**
     * 文件上传接口(处理文件)
     * @param file
     * @return
     * @throws Exception
     */
    @PostMapping("/uploadFile")
    public Dto<Object> uploadExcel(MultipartFile file) throws Exception {
        Dto<Object> dto = new Dto<>();
        //生成 WorkBook
        Workbook workbook = getWorkbook(file.getInputStream(), file.getOriginalFilename());
        //处理 Excel 文件
        String dealId = dealExcel(workbook);
        //将处理线程的 ID 返回给前端
        dto.setData(dealId);
        return dto;
    }

    /**
     * 实时返回处理进度的接口
     * @param dealId
     * @return
     */
    @GetMapping("/getDealPercent")
    public Dto<Object> getDealPercent(String dealId) {
        Dto<Object> dto = new Dto<>();
        //根据前端传来的 Id 获取处理线程
        DealThread dealThread = threadMap.get(dealId);
        if (dealThread == null) {
            dto.errorMsg("处理已结束");
            return dto;
        }
        //获取处理进度
        double dealPercent = dealThread.getDealPercent();
        dto.setData(dealPercent);
        return dto;
    }

    /**
     * 创建一个线程处理对应的工作簿
     * @param workbook
     * @return 处理线程的 ID
     */
    public String dealExcel(Workbook workbook) {
        //处理线程的 ID
        String id = UUID.randomUUID().toString();
        DealThread dealThread = new DealThread(id, workbook);
        Thread thread = new Thread(dealThread);
        threadMap.put(id, dealThread);
        thread.start();
        return id;
    }

    /**
     * 描述:根据文件后缀,自适应上传文件的版本
     *
     * @param inStr,fileName
     * @return
     * @throws Exception
     */
    public Workbook getWorkbook(InputStream inStr, String fileName) throws Exception {
        Workbook wb = null;
        String fileType = fileName.substring(fileName.lastIndexOf("."));
        if (EXCEL_2003_L.equals(fileType)) {
            wb = new HSSFWorkbook(inStr);  //2003-
        } else if (EXCEL_2007_U.equals(fileType)) {
            wb = new XSSFWorkbook(inStr);  //2007+
        } else {
            throw new Exception("解析的文件格式有误!");
        }
        return wb;
    }

    /**
     * 文件的处理线程
     */
    private class DealThread implements Runnable {

        private String dealId;
        private Workbook workbook;
        private final int MAX_ROW_NUM;
        private int currentRowNum = 0;

        /**
         * 获取处理进度
         *
         * @return
         */
        public double getDealPercent() {
            return currentRowNum * 1.0 / MAX_ROW_NUM;
        }

        public DealThread(String dealId, Workbook workbook) {
            this.dealId = dealId;
            this.workbook = workbook;
            Sheet sheetAt = workbook.getSheetAt(0);
            MAX_ROW_NUM = sheetAt.getLastRowNum() + 1;
        }

        public boolean isFinished() {
            return MAX_ROW_NUM <= currentRowNum;
        }

        @Override
        public void run() {
            Sheet sheet = workbook.getSheetAt(0);
            for (Row row : sheet) {
                try {
                    //休眠 30 毫秒,模拟复杂的处理过程
                    Thread.sleep(30);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                currentRowNum++;
            }
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

走过海棠暮

暂无简介

0 文章
0 评论
23 人气
更多

推荐作者

内心激荡

文章 0 评论 0

JSmiles

文章 0 评论 0

左秋

文章 0 评论 0

迪街小绵羊

文章 0 评论 0

瞳孔里扚悲伤

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文