form请求导出表格_vue 表格内容异步导出 - 人在路途

在做表格导出的时候,之前的框架一贯的做法是,导出拿到页面中缓存的查询条件,将条件参数在拼接,通过的方式将参数拼接给后台,在打开,

但是在实际过程会有一个问题,就是数据量特别大的时候,就会等待很长的时间,才跳转,如果这个时候一直点击导出,可能导致系统崩溃问题

解决办法:

异步导出,通过接口向后台发送查询参数,后台在返回一个标识,前段通过拿到的这个标识,进行轮询,如果获取到了路径,就打开并且关闭定时器

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

5bd49782bade00588552adbc6ffa60e8.gif a5ce672fdca2e980448540fd88146057.gif
<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>
View Code

abb4f6f4f97a99d6f0f5d776fe662e26.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值