在做表格导出的时候,之前的框架一贯的做法是,导出拿到页面中缓存的查询条件,将条件参数在拼接,通过的方式将参数拼接给后台,在打开,
但是在实际过程会有一个问题,就是数据量特别大的时候,就会等待很长的时间,才跳转,如果这个时候一直点击导出,可能导致系统崩溃问题
解决办法:
异步导出,通过接口向后台发送查询参数,后台在返回一个标识,前段通过拿到的这个标识,进行轮询,如果获取到了路径,就打开并且关闭定时器
handleExport(val) {
if(this.total > this.exportLimit){
this.$('导出数据个数不能大于'+this.exportLimit,{type:'warning'})
return
}
if (this.loadExcelTimer != null) {
(this.loadExcelTimer)
this.loadExcelTimer = null
}
this.$({text:'导出中……'})
this.$(this.url.export, this.exportParams).then(res => {
if (res.code == 200) {
this.loadExcelTimer = setInterval(() => {
this.getAsyncExcel(res)
}, 2000)
}
}).catch(err => {
this.restInterval()
this.$('导出失败');
})
},
getAsyncExcel(result) {
('export table...')
if (!) returnfalsethis.$(this.url.download, { id: }).then(res => {
if ( != null) {
this.restInterval()
//可以去下载了
let url = process.env.VUE_APP_URL2 + preUrl.files + //创建下载链接
let link = ('a') //创建a标签
link.style.display = 'none' //将a标签隐藏
link.href = url //给a标签添加下载链接
('download', '文件') //此处注意,要给a标签添加一个download属性,属性值就是文件名称,否则下载出来的文件是没有属性的,空白白 (link)
() //执行a标签 }
})
},
完整的vue
<template>
<TBLayout>
<!-- search-form -->
<content-box :slot="" :options="{width:'100%',padding:'20px 20px 0 20px'}">
<self-form :formInfos="searchFormInfos" :fields="searchFields" @setFields="changeFields" @button-click="handleButtonClick" />
</content-box>
<btns-group slot="btnsgroup" :data="batchButtons" @button-click="handleButtonClick" v-if="isShowTable" />
<!-- table -->
<self-table :slot="" v-if="isShowTable" :tableData="tableData" :tableInfos="tableInfos" :status="originBaseData" @selection-change="handleSelectionChange" @button-click="handleButtonClick" />
<!-- pager -->
<self-pager slot="pager" @button-click="handleButtonClick" v-if="isShowTable">
<el-pagination :current-page="pageNum" :page-sizes="pageSizes" :page-size="pageSize" :layout="layout" :total="total" slot="pagination" @size-change="handleSizeChange" @current-change="handleCurrentChange">
</el-pagination>
</self-pager>
<div slot="otherPager" class="chart-page" style="" v-if="!isShowTable">
<div class="echarts" ref="chart"></div>
</div>
</TBLayout>
</template>
<script>
import echarts from 'echarts'
import Crud from '@frameworks/assets/js/Crud'
import TBLayout from '@modules/baselayout/views/TBLayout'
import { searchFormInfos, batchButtons, tableInfos } from './PointHistory'
import { preUrl } from '@frameworks/conf/api'
import Api from '@frameworks/conf/api'
import { formatDate } from '@frameworks/assets/js/Filters'
export default {
mixins: [Crud],
components: { TBLayout },
data() {
return {
url: {
getData: Api.getPageByTime,
export: Api.exportHistory,
download: Api.downLoadExcel
},
detailParams: {
url: '',
params: {}
},
methodGet: 'post',
batchButtons,
searchFormInfos: searchFormInfos,
tableInfos: tableInfos,
isShowTable: true,//是否展示表格
checkNodes: [],//树选中的节点
chart: null,
resizeTimer: null,
chartOption: {
title: {
text: '趋势图'
},
tooltip: {
trigger: 'axis',
appendToBody: true,
formatter: (params) => {
let format = "yyyy-MM-dd HH:mm:ss"
let str = ""
for (let i = 0; i < params.length; i++) {
let p = params[i]
let node = this.checkNodes[]
let date = new Date()
str +=
'<tr><td style="color:' +
p.color +
'">' +
p.marker +
"</td><td>" +
p.seriesName +
":</td><td>" +
[1] +
( || '') +
"</td></tr>";
}
str =
"<p>" +
formatDate(params[0].data.name, format) +
"</p><table>" +
str +
"</table>";
return str
},
axisPointer: {
animation: false
}
},
xAxis: {
type: 'time',
splitLine: {
show: false
}
},
yAxis: {
name: '',
type: 'value',
boundaryGap: [0, '100%'],
splitLine: {
show: false
}
},
color: ['rgb(0, 137, 249)', 'rgb(0, 201, 134)', 'rgb(255, 132, 31)', 'rgb(216, 86, 207)', 'rgb(252, 206, 8)', 'rgb(133, 172, 193)'],
series: [{
name: '模拟数据',
type: 'line',
showSymbol: false,
hoverAnimation: false,
data: []
}]
},
exportLimit: 1000000,
unit: '',
loadExcelTimer: null
}
},
methods: {
async handleSearchBefore() {
let now = new Date().getTime()
this.searchFields.startTime = now - 7 * 24 * 3600 * 1000
this.searchFields.endTime = now
this.searchFormInfos.children[3].options.defaultValue = ''
this.searchFields.tagNames = ''
return await false
},
handleFieldsChangeBefore() {
deletethis.searchFields.checkd
deletethis.searchFields.data
deletethis.searchFields.initDefault
},
handleFieldsChangeAfter(val) {
if () {
this.searchFormInfos.children[3].options.pointType =
this.searchFields.tagNames = ''
} elseif () {
this.searchFormInfos.children[3].options.defaultValue =
this.checkNodes = val.field.checkNodes || []
}
},
//查
handleSearch(showMsg = false) {
if (this.searchFields.showTypeData == 1) {
this.isShowTable = true
} elseif (this.searchFields.showTypeData == 2) {
this.isShowTable = false
}
if (!this.isShowTable) {
this.$()
if (this.checkNodes && this.checkNodes.length > 10) {
this.$('曲线查看选择的测点不能超过10个,请重新选择', { type: 'warning' })
this.$()
returnfalse
}
}
this.handleFieldsChangeBefore && this.handleFieldsChangeBefore()
//如果是曲线是查所有的数据,表格的是需要进行分页的
let data = this.isShowTable ? Object.assign({
pageNum: this.startNum == 0 ? this.pageNum : this.startNum,
pageSize: this.pageSize,
}, this.searchFields) : this.searchFields
//统一删除showTypeData字段//delete data.showTypeDatadeletethis.searchFields.checkNodes
//获取数据this.$(this.url.getData, data, this.methodGet).then((res) => {
if (res.code == 200) {
//如果是表格if (this.isShowTable) {
this.startNum = 0
this.tableData = []
this.total = .total ? .total : 0
this.pageNum = .pageNum ? .pageNum : 1
this.pageCount = .pages ? .pages : 0
let result = this.isPager ? [this.dataListField] :
if (result.length == 0 && this.pageNum != 1) {//如果最后一页已经没有数据,那就查前一页if (this.searchForwardCount < 1) {
this.pageNum -= 1;
this.searchForwardCount += 1;
} else {
this.pageNum = 1;
}
this.handleSearch();
return
}
this.tableData = this.parseSearchResult(result)
//如果需要,把数据返回给父类this.$emit('dto-data', res)
//缓存查询条件this.isSearchParamsToLocalStorage && this.setSearchFieldStorage()
//获取数据后对数据进行修饰this.handleSearchSuccess && this.handleSearchSuccess(res, showMsg)
} else {//曲线this.initChart()
this.initData(res)
}
} else {
this.tableData = []
this.handleSearchFailed && this.handleSearchFailed(res)
}
this.searchForwardCount = 0;
}).catch(res => {
this.$()
this.searchForwardCount = 0;
this.tableData = []
this.handleSearchError && this.handleSearchError(res)
})
if (this.clearSelection) this.handleSelectionChange()
},
initChart() {
this.chart = echarts.init(this.$)
this.chart.clear()
this.chart.setOption(this.chartOption)
this.chart.resize()
},
handleExport(val) {
if(this.total > this.exportLimit){
this.$('导出数据个数不能大于'+this.exportLimit,{type:'warning'})
return
}
if (this.loadExcelTimer != null) {
(this.loadExcelTimer)
this.loadExcelTimer = null
}
this.$({text:'导出中……'})
// this.exportParams = {// startTime: 1607909692028,// endTime: 1608514492028,// pointType: 1,// tagNames: '',// showTypeData: 1,// rowNum: -1,// activeField: 'pointType',// timeZone: -8,// pageNum: 1,// pageSize: 10// }this.$(this.url.export, this.exportParams).then(res => {
if (res.code == 200) {
this.loadExcelTimer = setInterval(() => {
this.getAsyncExcel(res)
}, 2000)
}
}).catch(err => {
this.restInterval()
this.$('导出失败');
})
},
getAsyncExcel(result) {
('export table...')
if (!) returnfalsethis.$(this.url.download, { id: }).then(res => {
if ( != null) {
this.restInterval()
//可以去下载了
let url = process.env.VUE_APP_URL2 + preUrl.files + //创建下载链接
let link = ('a') //创建a标签
link.style.display = 'none' //将a标签隐藏
link.href = url //给a标签添加下载链接
('download', '文件') //此处注意,要给a标签添加一个download属性,属性值就是文件名称,否则下载出来的文件是没有属性的,空白白 (link)
() //执行a标签 }
})
},
initData(result) {
let rowData = && .list
this.unit = rowData[0].unitName
let legendArr = [], series = []
for (let item of this.checkNodes) {
()
}
//首先遍历一遍进行分组for (let i = 0; i < this.checkNodes.length; i++) {
let row = this.checkNodes[i]
(
{
name: legendArr[i] || row.id,
type: 'line',
showSymbol: false,
hoverAnimation: false,
data: this.getDataByCode(row, rowData)
}
)
}
this.$()
this.chart.setOption({
legend: {
data: legendArr
},
series
})
this.chart.resize()
},
//数据处理 getDataByCode(rowObj, rowData) {
let dataArr = []
for (let i = 0; i < rowData.length; i++) {
let row = rowData[i]
let _arr = []
(formatDate(, 'yyyy-MM-dd HH:mm:ss'))
()
rowObj.id == row.tagName && dataArr.push({
name: new Date(),
value: _arr,
unit:
})
}
return dataArr
},
init() {
window.onresize = () => {
return (() => {
if (this.resizeTimer) { clearTimeout(this.resizeTimer) }
this.resizeTimer = setTimeout(() => {
if (this.chart) {
this.chart.resize();
}
}, 300)
})()
}
},
restInterval() {
this.$()
(this.loadExcelTimer)
this.loadExcelTimer = null
}
},
mounted() {
this.init()
},
activated() {
this.searchFormInfos.children[3].options.pointType = '0'
this.searchFields.tagNames = ''
},
destroyed() {
this.restInterval()
},
};
</script>
<style lang="scss">
@import '@frameworks/assets/css/';
.chart-page {
box-shadow: 0 0 6px 1px rgba(0, 0, 0, );
border-radius: 8px;
height: 500px;
padding: 20px;
margin-right: 20px;
}
</style>