通过 Express 发回 CSV

Nic*_*ean 6 javascript csv file save express

我是从 JSON 导出 CSV 的新手...我非常接近得到这个...但我不知道如何从我的 Express 服务器将 CSV 发送回客户端。

用户选择要导出的客户,然后单击导出按钮...我希望发回 CSV 文件。

我在服务器上将 JSON 数据转换为 CSV,如何将此文件发送回客户端?

这是我迄今为止的快速路线 -

    router.post('/SaveCSV', (req, res) => {

    const csv = JSONToCSV(req.body, { fields: ["Customer Name", "Business Name", "Customer Email", "Customer ID", "School ID", "Student Count", "Admin Count", "Courses Count" ]})

    
    
})
Run Code Online (Sandbox Code Playgroud)

我已经尝试过 res.send、res.sendFile 和 res.attachment.. 有什么指导吗?

更新***

    router.post('/SaveCSV', (req, res) => {

    const csv = JSONToCSV(req.body, { fields: ["Customer Name", "Business Name", "Customer Email", "Customer ID", "School ID", "Student Count", "Admin Count", "Courses Count" ]})

    res.attachment('CustomerData.csv').send(csv)
    
})
Run Code Online (Sandbox Code Playgroud)

这是我在客户端上的 fetch 调用——

const saveCsv = async (customers) => {
    const token = await getAccessTokenSilently();
    try {
        const response = await fetch('/api/SaveCSV', {
            method: 'POST',
            headers: {
                Authorization: `Bearer ${token}`,
                "content-type": 'application/json; Charset=UTF-8'
            },
            body: JSON.stringify(customers)
        })
        const responseData = await response.json()
        console.log(responseData)
    } catch (error) {
        console.log(error)
    }
}
Run Code Online (Sandbox Code Playgroud)

Che*_*yDT 10

在服务器端,您可以只send返回 CSV 数据。默认情况下,它将附带内容类型text/html,但最好使用正确的类型发送text/csv。这可以通过使用first 来完成res.type('text/csv')

现在,如果您不将浏览器导航到端点,而是在前端代码中以编程方式使用下载,则是否有必要这样做是有争议的,但是: 将其标记为“下载”(不应显示,但实际保存)到文件),您可以使用res.attachment(). 如果您指定文件名,它还会在标头中发送该文件名,但还会根据扩展名自动设置内容类型。所以你可以使用res.attachment('customers.csv').send(csv)例如。如果浏览器导航到您的 URL,它会将 CSV 视为名称为 的文件下载customers.csv

router.post('/SaveCSV', (req, res) => {
    const csv = JSONToCSV(req.body, { fields: ["Customer Name", "Business Name", "Customer Email", "Customer ID", "School ID", "Student Count", "Admin Count", "Courses Count" ]})
    
    res.attachment('customers.csv').send(csv)
})
Run Code Online (Sandbox Code Playgroud)

在客户端,您可以使用 blob 形式获取原始响应正文response.blob(),并且可以让用户下载该 blob。有关如何做到这一点的更多说明,您可以在线研究(有很多关于这方面的资源)。这里有一个完整的示例,可以自动获取正确的文件名并与旧版浏览器一起使用(该示例也链接到此 Stack Overflow 答案的评论中) - 请注意,您需要text/csvapplication/pdf不是从响应中读取内容类型。

让我发布一个功能较少的简化示例:

const blob = await response.blob()
const link = document.createElement('a')
link.href = URL.createObjectURL(blob)
link.download = 'customers.csv'
link.click()
setTimeout(() => URL.revokeObjectURL(link.href), 0)
Run Code Online (Sandbox Code Playgroud)

但让我们想一想。根据您显示的代码,您的服务器代码所做的就是从前端获取数据,将其填充到 CSV 中并将其发回。我想说,你根本不需要服务器!您可以从前端代码中完成整个事情!

const saveCsv = (customers) => {
  const csv = JSONToCSV(customers, { fields: ["Customer Name", "Business Name", "Customer Email", "Customer ID", "School ID", "Student Count", "Admin Count", "Courses Count" ]})
  
  const link = document.createElement('a')
  link.href = 'data:text/csv,' + encodeURIComponent(csv)
  link.download = 'customers.csv'
  link.click()
}
Run Code Online (Sandbox Code Playgroud)

当然,这是假设您可以JSONToCSV在前端提供该库,或者您将添加自己的函数来构建 CSV 数据。