如何从我的 CSV 文件中删除 BOM 标题?



我正在尝试根据网页表格中显示的数据创建一个csv文件。

问题

每次我触发"保存到csv"功能时,文件都会在Excel中打开,但它不会解析出各个字段(使用逗号分隔符)。 所有内容将始终显示在一列中。 它将正确地打破不同的界限。 经过大量的测试/故障排除和堆栈溢出的帮助,最终我真正的问题是正在添加 BOM 标头并且似乎将其搞砸了。 当我在记事本++中打开csv文件并更改编码以删除BOM标头,然后在Excel中重新打开该文件时,它看起来很好。

法典

代码如下所示:(注意:非IE路径工作正常。

function exportTableToCSV($tableName, fileName) {
var csv = GetCellValues($tableName);
console.log(csv);
console.log("filename is:" + fileName);
if (navigator.userAgent.search("Trident") >= 0) {
//this is the path that is execute in IE10 browser...
window.CsvExpFrame.document.open("text/html", "replace");
window.CsvExpFrame.document.write(csv);
window.CsvExpFrame.document.close();
window.CsvExpFrame.focus();
window.CsvExpFrame.document.execCommand('SaveAs', true, fileName + ".csv");
} else {
var uri = "data:text/csv;charset=utf-8," + escape(csv);
var downloadLink = document.createElement("a");
downloadLink.href = uri;
downloadLink.download = fileName + ".csv";
document.body.appendChild(downloadLink);
downloadLink.click();
document.body.removeChild(downloadLink);
}
};

问题

如何以编程方式删除 BOM 标头?

到目前为止我尝试过什么

到目前为止,我已经尝试了以下代码更改:

  1. 尝试更改/指定编码,如下所示:(此处注释掉了所有行...但我循环浏览了每一个并重试导出)

    //窗。CsvExpFrame.document.open("text/html", "replace"); 窗。CsvExpFrame.document.open('data:text/csv;视窗-1252;') 窗。CsvExpFrame.document.open('data:text/csv;字符集=UTF-8;') 窗。CsvExpFrame.document.open('data:text/csv;字符集=UTF-8,')

  2. 尝试像这样删除标题:

    //csv = csv.replace(/\uFFFD/g, '') csv = csv.replace(/\uFEFF/g, '') 窗。CsvExpFrame.document.write(csv);

到目前为止,没有任何效果。 如果您对我有任何建议,我将不胜感激。 我一直在阅读有关stackoverflow的其他类似帖子并尝试它们,但到目前为止,这是不行的。 我还没有找到一个特定于javascript的。

谢谢。

编辑 1

自从发布这个问题以来,我发现了一些额外的/有用的工件:

当我在记事本++中打开文件时,编码设置为"UCS-2 LE BOM"。
我注意到将文件另存为:

"UTF-8 BOM" fixes the issue.
"UTF-8" (aka no BOM) fixes the issue
"UCS-2 BE BOM"  almost works but it adds some funky characters the first field's header, so it looks like this: 
þÿ"Group Name"

我尝试更改我的代码以显式添加 BOM 标头,如下所示:

window.CsvExpFrame.document.open("text/html", "replace");
window.CsvExpFrame.document.write("uFEFF"+csv); // ADD BOM 
//window.CsvExpFrame.document.write(csv);
window.CsvExpFrame.document.close();
window.CsvExpFrame.focus();
window.CsvExpFrame.document.execCommand('SaveAs', true, fileName + ".csv");

但根据记事本++,此代码不会更改编码。它仍然设置为LE BOM。
最后,我创建了这个 csv 文件的 2 个版本。 两者都是由 Web 应用程序生成的。 但是对于第二个文件,我使用Notepad++将编码更改为有效的编码。 然后我使用"Meld"尝试对两个文件进行差异,但它们看起来是相同的。

编辑 2

如果我更改逻辑以便没有对 IE 三叉戟进行条件检查,但代码总是这样做:

function exportTableToCSV($tableName, fileName) {
var csv = GetCellValues($tableName);
console.log(csv);
console.log("filename is:" + fileName);
var uri = "data:text/csv;charset=utf-8," + encodeURIComponent(csv);
var downloadLink = document.createElement("a");
downloadLink.href = uri;
downloadLink.download = fileName + ".csv";
document.body.appendChild(downloadLink);
downloadLink.click();
document.body.removeChild(downloadLink);
}

IE 炸弹并显示以下错误:

SCRIPT122:传递给系统调用的数据区域太小。

它在"downloadLink.click();"调用上失败了。

这是我认为的解决方案,将 CSVString转换为Blob,然后转换为ObjectURL,对于 IE10+,使用navigator.msSaveBlob

function exportCSV(csv, filename) {
if (!filename) {filename = 'export.csv';}
var blob = new Blob([csv], {type: 'text/csv;charset=utf-8;'});
if (!navigator.msSaveBlob) {
var link = document.createElement("a");
var url = URL.createObjectURL(blob);
link.setAttribute("href", url);
link.setAttribute("download", filename);
link.style.visibility = 'hidden';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
URL.revokeObjectURL(blob);
} else {
navigator.msSaveBlob(blob, filename); // IE 10+
}
}

在实施之后:

function exportTableToCSV($tableName, fileName) {
var csv = GetCellValues($tableName); console.log(fileName, csv);
exportCSV(csv, fileName);
}

在Chrome,Firefox和IE11中进行了测试,有数千行。

最新更新