You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue项目中DiscogsCSV的CSV文件下载功能失效求助

Vue项目中Discogs数据已获取但无法触发CSV文件下载

项目功能定位

  • 导入首列为有效Discogs发行ID的.csv文件
  • 通过Discogs API查询这些发行ID
  • 输出附加以下多列Discogs发行数据的新.csv文件:
    release_id、artist、format、qty、format descriptions、label、catno、country、year、genres、styles、barcode、tracklist

当前代码

App.vue

<template>
    <div>
        <button @click="downloadSampleInputFile">Download sample file</button>
    </div>

    <div>
        <FileUpload @file="setFile" />
    </div>

    <div>
        <p v-for="row of data" :key="row">
            {{ row }}
        </p>
    </div>

</template>

<script lang="ts">
import { defineComponent } from 'vue';
import FileUpload from '@/components/FileUpload.vue';
import { fetchRelease, parseCsvToArray } from "@/parser";
import { prepareDownload } from './components/PrepareDownload';
import { downloadSampleInputFile } from './components/DownloadSampleInputFile';

export default defineComponent({
    name: 'App',
    components: {
        FileUpload,
    },
    data() {
        return {
            data: null as null | string[],
        }
    },
    methods: {
        async downloadSampleInputFile() {
            const link = document.createElement('a');
            link.href = '/src/assets/test_5_lines.csv';
            link.target = '_blank';
            link.download = 'test_5_lines.csv';
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
        },
        async setFile(file: File) {
            this.data = await parseCsvToArray(file)
            console.log(this.data)
        },
        async fetchReleases(idList: string[]) {
            try {
                const releases = await fetchRelease(idList)
                console.log('Fetched releases from Discogs', releases)
                return releases
            } catch (err) {
                console.log('Failed fetching releases', err)
            }
        },
        async downloadCSV(releases: any[]) {
            prepareDownload(releases)
        },
        
    },
    watch: {
        data(data) {
            this.fetchReleases(data)
        }
    },
});
</script>

fetchRelease.ts

import { DiscogsClient } from '@lionralfs/discogs-client';
import { processReleaseData } from './ProcessReleaseData';

export default  {
  name: 'FetchRelease',
  methods: {
    fetchRelease
  }
}

const db = new DiscogsClient().database();

async function fetchRelease(releaseId: string): Promise<any[] | { error: string }> {
  try {
    const { data } = await db.getRelease(releaseId);
    return processReleaseData(releaseId, data);
  } catch (error) {
    return {
      error: `Release with ID ${releaseId} does not exist`
    };
  }
}

PrepareDownload.ts

import { ROW_NAMES } from './RowNames';

export default  {
  name: 'PrepareDownload',
  methods: {
    prepareDownload
  }
}

export function prepareDownload(releases: any[]) {
    const csvContent = "releases:text/csv;charset=utf-8," + ROW_NAMES.join(",") + "
" + releases.map(e => e.join(",")).join("
");
    const encodedUri = encodeURI(csvContent);
    const link = document.createElement("a");
    link.setAttribute("href", encodedUri);
    link.setAttribute("download", "my_data.csv");
    document.body.appendChild(link); // Required for Firefox
    link.click();
  }

问题现状

已成功获取Discogs数据并在控制台打印,但downloadCSV方法无法触发文件下载。

问题排查与修复方案

1. downloadCSV未被调用

当前代码中,fetchReleases获取到数据后仅打印到控制台,未触发下载逻辑。修改watch钩子,在数据就绪后调用downloadCSV:

watch: {
  async data(data) {
    if (data?.length) {
      const releases = await this.fetchReleases(data);
      if (releases) {
        this.downloadCSV(releases);
      }
    }
  }
}

2. fetchRelease参数不匹配

fetchRelease定义为接收单个releaseId字符串,但fetchReleases传入的是ID数组,需改为批量并行请求:

// 修改fetchReleases方法
async fetchReleases(idList: string[]) {
  try {
    // 并行请求所有ID
    const releases = await Promise.all(
      idList.map(id => fetchRelease(id))
    );
    // 过滤掉错误条目
    const validReleases = releases.filter(item => !item.error);
    console.log('Fetched valid releases from Discogs', validReleases);
    return validReleases;
  } catch (err) {
    console.log('Failed fetching releases', err);
    return null;
  }
}

// 修改fetchRelease.ts的导出方式,确保函数能被正确导入
export async function fetchRelease(releaseId: string): Promise<any[] | { error: string }> {
  // ...原有逻辑不变
}

3. CSV生成逻辑错误

  • MIME类型前缀错误:"releases:text/csv;charset=utf-8,"应改为标准的"data:text/csv;charset=utf-8,"
  • 换行符无效:代码中的" "是无效换行,需替换为"\n"
  • 未处理特殊字符:字段中的逗号、引号会破坏CSV格式,需用双引号包裹字段并转义内部引号

修改后的PrepareDownload.ts:

import { ROW_NAMES } from './RowNames';

export function prepareDownload(releases: any[]) {
  // 处理表头和行数据,包裹特殊字符
  const header = ROW_NAMES.join(',');
  const rows = releases.map(row => 
    row.map(field => `"${String(field).replace(/"/g, '""')}"`).join(',')
  );
  // 拼接正确的CSV内容
  const csvContent = `data:text/csv;charset=utf-8,${header}\n${rows.join('\n')}`;
  const encodedUri = encodeURI(csvContent);
  const link = document.createElement("a");
  link.href = encodedUri;
  link.download = "discogs_releases.csv";
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link); // 清理DOM元素
}

4. 示例文件路径优化(可选)

downloadSampleInputFile中的/src/assets/test_5_lines.csv在生产环境会失效,建议将静态文件移至public目录,路径改为/test_5_lines.csv。

内容的提问来源于stack exchange,提问作者double-happiness

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 14:14:52