如何从我的csv文件中删除BOM表头?

时间:2017-05-03 12:53:22

标签: javascript excel csv internet-explorer

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

问题

每当我触发“保存到csv”功能时,该文件将在Excel中打开,但不会解析出各个字段(使用逗号分隔符)。一切都会出现在一列中。它会恰当地打破不同的线条。 在经过多次测试/故障排除以及来自stackoverflow的帮助之后,最终我的真正问题是添加了BOM头并且似乎搞乱了它。当我在Notepad ++中打开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. 尝试更改/指定编码,如下所示:(所有行都在这里注释掉......但我循环遍历每一行并重新导出)

    // window.CsvExpFrame.document.open(“text / html”,“replace”); //window.CsvExpFrame.document.open('data:text/csv;windows-1252;') //window.CsvExpFrame.document.open('data:text/csv;charset=utf-8;') //window.CsvExpFrame.document.open('data:text/csv;charset=utf-8,')

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

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

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

    感谢。

    编辑1

    自发布此问题以来,我发现了一些其他/有用的工件:

    当我在Notepad ++中打开文件时,编码设置为“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");
    

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

    编辑2

    如果我改变逻辑以便IE trident没有条件检查,但代码总是这样做:

    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();”上失败了调用

1 个答案:

答案 0 :(得分:2)

以下是我认为的解决方案,将CSV String转换为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中测试过几千行。