JS 在 Excel 中构建了 # 之后的 CSV 中断

JS built CSV breaking after # in Excel

提问人:Rory L. 提问时间:9/17/2020 最后编辑:Rory L. 更新时间:9/17/2020 访问量:1846

问:

我正在通过 JavaScript 构建 CSV,一些单元格值包含主题标签和其他特殊字符。我特别注意到,主题标签充当了文件的硬停止。我无法在网上找到解决方案,也没有真正看到这个特定问题。我已经尝试了修复程序,但无济于事。下面是我用来构建 CSV 的函数。\uFEFF

export const buildCSV = (headers, data) => {
  if (!headers && !data) return;

  let csvContent = "data:text/csv;charset=UTF-8,";

  if (headers) {
    csvContent += headers.join(",") + "\r\n";
  }

  if (data) {
    data.forEach(row => {
      csvContent += row.join(",") + "\r\n";
    });
  }

  return encodeURI(csvContent);
};

作为参考,目前,在打开 CSV 时,诸如 will show as 和其余行被截断的值。150 # content150

提前感谢任何花时间提供答案的人!

javascript excel csv 特殊字符

评论

0赞 TKoL 9/17/2020
为什么?encodeURI
0赞 Rory L. 9/17/2020
因此,用户可以使用<a>

答:

1赞 gkulshrestha 9/17/2020 #1

从这里的答案中挑选线索 JavaScript blob 文件名没有链接

下面给出的代码的最小复制似乎正在工作。它依赖于 HTML5 中的 download 属性。因此,不支持较旧的浏览器。但是,如果您想要这种支持,上面的链接有更多答案,您可以查看。

<script>
 const buildCSV = (headers, data) => {
  if (!headers && !data) return;

  let csvContent = "";

  if (headers) {
    csvContent += headers.join(",") + "\r\n";
  }

  if (data) {
    data.forEach(row => {
      csvContent += row.join(",") + "\r\n";
    });
  }
return csvContent;
}

function downloadFile()
{
 function download(data, fileName) {
      var a = document.createElement("a");
    document.body.appendChild(a);
    a.style = "display: none";
            blob = new Blob([data], {type: "text/csv"}),
            url = window.URL.createObjectURL(blob);
        a.href = url;
        a.download = fileName;
        a.click();
        window.URL.revokeObjectURL(url);
    };
var data = buildCSV(['header1','header2','header3'],[['150#content','rowvalue1','rowvalue2']]),
    fileName = "myfile.csv";
    download(data, fileName);
}

</script>
<body>
<a href="" onclick="downloadFile()" >Download</a>
</body>
11赞 Rory L. 9/17/2020 #2

我设法通过进行此切换来解决问题:

  const encodedURI = encodeURI(csvContent);
  const fixedEncodedURI = encodedURI.replaceAll('#', '%23');
  return fixedEncodedURI;

在运行 encodeURI 之前执行切换会导致结果为“%23”,而不是正确地将其转换回井号标记。根据 MDN(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI#Description),该函数不会转义主题标签(在其他字符中,但我没有注意到其他字符的问题)。手动编码后,一旦在 Excel 中下载并打开它们,它们就会转换回主题标签。encodeURI

TKoL 创建了一个小提琴,展示了产生所需输出的用法。当我在尝试使用此函数时遇到问题时,需要注意的一些事项是必须对初始代码进行以下更改,否则将导致下载失败:encodeURIComponent

let csvContent = "";

other code...

return "data:text/csv;charset=utf-8," + encodeURIComponent(csvContent);

感谢所有提供潜在解决方案的人!

评论

0赞 Rory L. 9/17/2020
一旦系统允许我,我就会接受这个答案,这显然是在 2 天内。
0赞 TKoL 9/17/2020
那 ,哪个确实取代了主题标签呢?encodeURIComponent
3赞 TKoL 9/17/2020
我制作了这个jsfiddle来测试encodeURIComponent
0赞 Rory L. 9/17/2020
嗯,这确实有效。在尝试该解决方案时,我的问题是,如果在运行之前添加到变量中,则会导致下载失败。但是,显然,如果您将数据规范添加到结果中,它将按预期运行。data:text/csv;charset=UTF-8,csvContentencodeURIComponentencodeURIComponent
0赞 TKoL 9/17/2020
您是否考虑过改用 blob 创建 uri?gist.github.com/dhunmoon/d743b327c673b589e7acfcbc5633ff4b