生成进度条(动态生成文件,并前端显示生成进度)
2017-11-22 16:58
176 查看
注:
1.本文是以生成txt文件为例子。2.写的主要是一个思路,不一点非要是生成txt,可以是其他类型文件。
3.本文例子的项目地址:https://github.com/smallsnail-wh/wh
思路
在前端显示,需要拿到生成的进度(百分比)。生成的进度为当前生成总量占需要生成总量的百分比。
需要生成的总量可以从前端输入得到(或者其他方式输入)。
当前生成总量在代码中设置计数变量得到。
我的实现方案
前端传生成总量到后端。后端更具得到的生成总量生成txt。因为生成txt是耗时任务,所以启用线程生成。在线程中设置计数变量每生成一行数据,计数变量加1,并与生成总量计算出百分比。然后将百分比存入redis中。
在步骤2的同时,前端没个1秒或者2秒向后端发送请求,查询redis中存储的百分比。后端返回百分比,以供前端显示。
当百分比为100%后,前端发请求,删除redis中的数据。(为了防止下次生成不出错)
前端提供下载链接,以供下载。
实施
准备工作,我后端用了spring boot,数据库用redis代替(速度快),前端用了vue和基于Vue的UI组件库iview网页代码如下:
index.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>mian</title> <link rel="stylesheet" type="text/css" href="http://unpkg.com/iview/dist/styles/iview.css"> <script type="text/javascript" src="http://vuejs.org/js/vue.min.js"></script> <script type="text/javascript" src="http://unpkg.com/iview/dist/iview.min.js"></script> <script src="https://unpkg.com/axios/dist/axios.min.js"></script> </head> <body> <div id="app"> <div style="text-align: center;margin-top: 200px"> <div style="margin-bottom: 25px;margin-top: 50px"> 数量: <i-input v-model="count" placeholder="请输入..." style="width: 200px"></i-input> <strong style="color: rgb(210, 15, 15);margin-right: 25px">{{count/10000}}万</strong> </div> <div> <i-progress :percent="percent" style="width: 300px;margin-bottom: 25px"/> </div> <div> <i-button v-if="codeCreate" type="primary" @click="create()" style="margin-left: 230px">生成</i-button> <strong v-if="codeCreating" style="color: rgb(44, 204, 130);margin-left: 190px">正在生成TXT文件</strong> <a :href="'temp/progress.txt'" download="download"> <i-button v-if="codeDownload" type="success" style="margin-left: 10px;margin-left: 230px">下载</i-button> </a> </div> </div> </div> <script> new Vue({ el: '#app', data: { /*用于展示的百分数*/ percent: 0, /*控制组件是否显示*/ codeCreate: true, /*控制组件是否显示*/ codeCreating: false, /*控制组件是否显示*/ codeDownload: false, /*需要生成的数量*/ count: null }, mounted(){ console.log(axios.defaults); }, methods: { /*生成按钮的点击事件*/ create(){ var r = /^\+?[1-9][0-9]*$/; //正整数 if(r.test(this.count)){ axios({ method: 'post', url: '/wh/progress', data: { "count": this.count+"" }, dataType:'json' }).then(function (response) { if(response.data =="SUCCESS"){ this.codeCreate = false; this.codeCreating = true; this.getProgressPercent(); }else{ this.$Message.error("生成失败,请检查后重新生成!"); } }.bind(this)).catch(function (error) { alert(error); }); }else{ this.$Message.error("必须为数字!"); } }, /*从后台拿到半分比数*/ getProgressPercent(){ setTimeout(() => { axios({ method: 'get', url: '/wh/progress', dataType:'json' }).then(function (response) { if(response.data != null){ if(response.data != "100"){ this.percent = parseInt(response.data); this.getProgressPercent(); }else{ this.percent = parseInt(response.data); this.delPercentInRedis(); this.codeCreating = false; this.codeDownload = true; this.$Message.info('生成完成'); } }else { this.getProgressPercent(); } }.bind(this)).catch(function (error) { alert(error); }); }, 1000); }, /*txt生成后删除redis中对应的数据*/ delPercentInRedis(){ axios({ method: 'delete', url: '/wh/progress', data: {}, dataType:'json' }).then(function (response) { }.bind(this)).catch(function (error) { alert(error); }); } } }) </script> </body> </html>
3.后端的配置和redis的集成(网上很多)下面是主要的代码:
Controller
import java.util.Map; import javax.annotation.Resource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; import com.wanghuan.service.ProgressService; @RestController public class CreateProgressController { Logger log = LoggerFactory.getLogger(CreateProgressController.class); @Resource(name = "progressService") private ProgressService progressService; /** * 生成txt请求 * * @param reqMap * @return */ @PostMapping(value = "/progress") public String create(@RequestBody Map<String, Object> reqMap) { log.info(reqMap.toString()); progressService.createTxt(Long.parseLong((String) reqMap.get("count"))); return "SUCCESS"; } /** * 得到进度请求 * * @return */ @GetMapping(value = "/progress") public String getPercent() { return progressService.getPercent(); } /** * 删除redis中数据请求 * * @return */ @DeleteMapping(value = "/progress") public String delPercentInRedis() { log.info("删除成功!"); progressService.delPercentInRedis(); return "SUCCESS"; } }
Service
public interface ProgressService { /** * 生成txt文本 * @param count */ void createTxt(long count); /** * 得到进度 */ String getPercent(); /** * 删除redis中的缓存 */ void delPercentInRedis(); }
ServiceImpl
import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.core.ValueOperations; import org.springframework.stereotype.Service; import com.wanghuan.dao.ProgressDao; import com.wanghuan.service.ProgressService; @Service("progressService") public class ProgressServiceImpl implements ProgressService { Logger log = LoggerFactory.getLogger(ProgressServiceImpl.class); @Autowired private RedisTemplate redisTemplate; @Autowired private StringRedisTemplate stringRedisTemplate; @Autowired ProgressDao progressDao; @Override public void createTxt(long count) { new Thread() { public void run() { try { Thread.sleep(500); long startCount = 1; long endCount = count; long pcount = count / 100; File file = new File("target/classes/static/temp/progress.txt"); String path = file.getAbsolutePath(); FileWriter fw = new FileWriter(file); BufferedWriter bw = new BufferedWriter(fw); /*计数变量*/ long currentCount = 0; String percent = "0"; String percentCopy = "0"; for (; startCount <= endCount; startCount++) { currentCount++; percentCopy = percent; if (count < 10000) { percent = String.valueOf((currentCount * 100 / count)); } else { percent = String.valueOf((currentCount / (pcount))); } if ("100".equals(percent) && currentCount != count) { percent = "99"; } if (!percentCopy.equals(percent)) { System.out.println(percent); ValueOperations<String, String> value = stringRedisTemplate.opsForValue(); value.set("percent", percent); } String s; s = "WH" + currentCount; // 写入txt文件 bw.append(s + "\r\n"); } bw.flush(); bw.close(); log.info("txt文件名" + "progress.txt"); } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } }.start(); } @Override public String getPercent() { String progress = "0"; ValueOperations<String, String> value = stringRedisTemplate.opsForValue(); progress = value.get("percent"); return progress; } @Override public void delPercentInRedis() { stringRedisTemplate.delete("percent"); } }
相关文章推荐
- JavaWeb项目实现文件上传动态显示进度
- 让动态生成的图表以.png文件显示
- File Uploader:支持进度显示与文件拖拽的多文件上传前端JS脚本
- JavaWeb项目实现文件上传动态显示进度
- Java动态显示文件上传进度的简单实现
- Java动态显示文件上传进度的简单实现
- Java动态显示文件上传进度的简单实现
- jsp+Extjs实现动态显示文件上传进度
- 利用jsp+Extjs实现动态显示文件上传进度
- 利用jsp+Extjs实现动态显示文件上传进度
- JavaWeb项目实现文件上传动态显示进度
- ssm项目使用Mybatis动态拼接sql语句,生成的sql中文全部显示为???的问题(配置文件sql语句中文解析问题)
- Web前端文件上传进度的显示
- Java动态显示文件上传进度的简单实现
- JavaWeb项目实现文件上传动态显示进度
- JavaWeb项目实现文件上传动态显示进度
- JavaWeb项目实现文件上传动态显示进度
- jsp+Extjs实现动态显示文件上传进度
- 前端数据传到后台动态生成Excel文件并提供文件下载
- PHP+Ajax实现上传文件进度条动态显示进度功能