Java 实时显示处理进度条功能
整体思路:一个接口负责接收前端上传的文件,并创建线程处理该文件;另一个接口负责实时返回当前文件的处理进程(前端轮询)。
@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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论