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
相关产品推荐
相关产品推荐

