我正在尝试根据网页表格中显示的数据创建一个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 标头?
到目前为止我尝试过什么
到目前为止,我已经尝试了以下代码更改:
尝试更改/指定编码,如下所示:(此处注释掉了所有行...但我循环浏览了每一个并重试导出)
//窗。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,')
尝试像这样删除标题:
//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中进行了测试,有数千行。