【问题标题】:Download after completing the request - vue-json-excel完成请求后下载 - vue-json-excel
【发布时间】:2026-02-11 20:05:01
【问题描述】:

我正在使用 vue-json-excel 库来帮助我从 json 下载数据。

在 vue 的视图中我拥有的位置:

<div class="column is-narrow" @click="btDispatch">
    <json-excel
      class   = "button is-primary"
     :data   = "routes"
     :fields = "json_fields_routes"
     :name    = "`descarga-rutas.xls`">
    <span class="icon"><i class="fa fa-download"></i></span><span>Descargar entregas</span>
   </json-excel>

其中:data = "routes" 是要下载的 json:

data () {
  return {
     json_fields_routes: {
       ruta_id: 'id',
       fecha: 'date',
       estado_codigo: 'route_state',
       estado: 'estado',
       vehículo: 'vehicle',
       conductor_codigo: 'worker.id',
       conductor_nombre: 'worker.name',
       hora_inicio: 'date_start_web',
       hora_fin: 'date_end_web',
       entregas: 'dispatches_count',
       pendientes: 'pendientes',
       entregados: 'entregados',
       parciales: 'parciales',
       no_entregados: 'noEntregados',
     },
     json_meta: [
      [
        {
          key: 'charset',
          value: 'utf-8',
        },
      ],
    ],
  }
}

根据文档,我必须这样做才能下载 Excel 并且它可以正常工作。我遇到的问题是它是在有现有数据时下载的,但是我正在处理来自服务器的数据并且之前在 load() 中加载了数据但是当有大量数据时需要很长时间进入页面的那个部分,所以我更喜欢下载按钮编译数据然后下载。

到目前为止我有:

methods: {
  btRoute() {
        this.axios.post('/routesdownload/filter_route/', this.params)
            .then((response) => {
              this.routes = response.data.results;
              for (let i = 0; i < this.routes.length; i++) {
                this.routes[i].pendientes = this.filterByStatus(this.routes[i].dispatches, 1);
                this.routes[i].entregados = this.filterByStatus(this.routes[i].dispatches, 2);
                this.routes[i].parciales = this.filterByStatus(this.routes[i].dispatches, 3);
                this.routes[i].noEntregados = this.filterByStatus(this.routes[i].dispatches, 4);
                this.routes[i].date = moment(this.routes[i].date).format('YYYY/MM/DD');
                if (this.routes[i].date_start_web && this.routes[i].date_end_web != null) {
                  this.routes[i].date_start_web
                  = moment(this.routes[i].date_start_web).format('YYYY/MM/DD HH:mm:ss');
                  this.routes[i].date_end_web
                  = moment(this.routes[i].date_end_web).format('YYYY/MM/DD HH:mm:ss');
                } else {
                  this.routes[i].date_start_web = '-';
                  this.routes[i].date_end_web = '-';
                }
                if (this.routes[i].route_state === 1) {
                  this.routes[i].estado = 'Borrador';
                } else if (this.routes[i].route_state === 2) {
                  this.routes[i].estado = 'Publicado';
                } else if (this.routes[i].route_state === 3) {
                  this.routes[i].estado = 'Iniciado';
                } else {
                  this.routes[i].estado = 'Terminado';
                }
              }
            });
      },
}

但这只是根据需要带来数据和武器,但是你在完成应用程序后怎么能用这个库调用你下载的函数呢?我可以使用 callbackpromise 来做到这一点,但是如何调用该下载函数呢?

【问题讨论】:

  • 哪个阶段慢;下载数据还是处理它?运行性能测试并找出您需要集中精力的地方。
  • 它没有那个能力。如果您想使用它,请通过计算属性传递您要下载的数据,并且在数据加载完成之前不要让用户单击下载按钮。否则,您将不得不查看其他库,或者您可以自己制作(我选择了这个解决方案)
  • 感谢@NafiulIslam 的建议

标签: vue.js callback promise vuejs2 vue-component


【解决方案1】:

我以为是响应有点晚了,但是新版本的 vue-json-excel 支持一个回调 prop 来在下载文件之前获取数据。

<json-excel
  class   = "button is-primary"
  fetch = "MyCallbackFetchData"
 :fields = "json_fields_routes">

 Descargar Archivo
</json-excel>

回调可以使用 async...await 选项运行,因此您可以使用异步调用,例如:

methods:{
  async MyCallbackFetchData(){
      return await axios.get('myapiurl');
  }
}

重要提示:此选项仅在道具数据未定义时有效。如果定义了数据,则使用该信息生成的文件。

【讨论】:

    【解决方案2】:

    显然,该库没有该功能。 然后到组件我放了一个 ref:

    <json-excel
          ref="droute"
          class   = "button is-primary"
         :data   = "routes"
         :fields = "json_fields_routes"
         :name    = "`descarga-rutas.xls`">
        <span class="icon"><i class="fa fa-download"></i></span><span>Descargar entregas</span>
       </json-excel>
    

    承诺结束时(已加载数据):

    this.$refs.droute.$el.click();
    

    我调用组件并下载。

    【讨论】:

      【解决方案3】:

      就我而言,我使用了两个按钮,一个用于加载数据,一个用于下载。而且它更容易实现

      【讨论】:

      • 所以你的意思是用户应该按顺序使用这两个按钮?