您的位置:首页 > Web前端

生成进度条(动态生成文件,并前端显示生成进度)

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");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  后端