使用JavaScript将文件下载为.csv文件

42

我正在尝试将文件导出为.csv格式,以便当用户单击下载按钮时,浏览器会自动将文件下载为.csv格式。 我还想能够设置要导出的.csv文件的名称。

我正在使用JavaScript来实现这一点。

以下是代码:

function ConvertToCSV(objArray) {
  var array = typeof objArray != 'object' ? JSON.parse(objArray) : objArray;
  var str = '';

  for (var i = 0; i < array.length; i++) {
    var line = '';
    for (var index in array[i]) {
      if (line != '') line += ','

      line += array[i][index];
    }

    str += line + '\r\n';
  }

  return str;
}

// Example
$(document).ready(function () {

  // Create Object
  var items = [
    { "name": "Item 1", "color": "Green", "size": "X-Large" },
    { "name": "Item 2", "color": "Green", "size": "X-Large" },
    { "name": "Item 3", "color": "Green", "size": "X-Large" }];

  // Convert Object to JSON
  var jsonObject = JSON.stringify(items);

  // Display JSON
  $('#json').text(jsonObject);

  // Convert JSON to CSV & Display CSV
  $('#csv').text(ConvertToCSV(jsonObject));

  $("#download").click(function() {
    alert("2");
    var csv = ConvertToCSV(jsonObject);
    window.open("data:text/csv;charset=utf-8," + escape(csv))
    ///////

  });

});

你成功地解决了这个问题吗? - pato.llaguno
6个回答

43

我在这个帖子中写了一个解决方案:如何使用window.open设置文件名

这是一个简单的解决方案:

$("#download_1").click(function() {
    var json_pre = '[{"Id":1,"UserName":"Sam Smith"},{"Id":2,"UserName":"Fred Frankly"},{"Id":1,"UserName":"Zachary Zupers"}]';
    var json = $.parseJSON(json_pre);

    var csv = JSON2CSV(json);
    var downloadLink = document.createElement("a");
    var blob = new Blob(["\ufeff", csv]);
    var url = URL.createObjectURL(blob);
    downloadLink.href = url;
    downloadLink.download = "data.csv";

    document.body.appendChild(downloadLink);
    downloadLink.click();
    document.body.removeChild(downloadLink);
});

JSON2CSV函数:

function JSON2CSV(objArray) {
    var array = typeof objArray != 'object' ? JSON.parse(objArray) : objArray;
    var str = '';
    var line = '';

    if ($("#labels").is(':checked')) {
        var head = array[0];
        if ($("#quote").is(':checked')) {
            for (var index in array[0]) {
                var value = index + "";
                line += '"' + value.replace(/"/g, '""') + '",';
            }
        } else {
            for (var index in array[0]) {
                line += index + ',';
            }
        }

        line = line.slice(0, -1);
        str += line + '\r\n';
    }

    for (var i = 0; i < array.length; i++) {
        var line = '';

        if ($("#quote").is(':checked')) {
            for (var index in array[i]) {
                var value = array[i][index] + "";
                line += '"' + value.replace(/"/g, '""') + '",';
            }
        } else {
            for (var index in array[i]) {
                line += array[i][index] + ',';
            }
        }

        line = line.slice(0, -1);
        str += line + '\r\n';
    }
    return str;
}

你从哪里获取 JSON2CSV(json) 这个库? - pato.llaguno
感谢@Jewel这很有帮助...我保存了一个包含标题行的JS fiddle,链接在这里:https://jsfiddle.net/m788fu63/1/。 - Dan

41

在现代浏览器中,锚点有一个新的属性。

download

http://caniuse.com/download

因此,不必使用

window.open("data:text/csv;charset=utf-8," + escape(csv))

创建一个下载链接:

<a href="data:text/csv;charset=utf-8,'+escape(csv)+'" download="filename.csv">download</a>

另一个解决方案是使用PHP。

编辑

我不使用jQuery,但您需要编辑代码以添加下载链接, 可以在您的函数中使用类似以下内容的代码。

var csv=ConvertToCSV(jsonObject),
a=document.createElement('a');
a.textContent='download';
a.download="myFileName.csv";
a.href='data:text/csv;charset=utf-8,'+escape(csv);
document.body.appendChild(a);

1
嗨,但我无法下载我想要的内容,是否还有其他代码需要编辑? - Samuel Tang
你的意思是什么?使用其中一个支持的浏览器(例如Chrome)。使用JavaScript动态插入href数据和下载文件名。 - cocco
1
'+escape(csv)+' 这是我在Excel文件中看到的。 - Samuel Tang
因为你可能已经将html复制到了页面上。他建议你使用javascript“创建”csv链接,因此'+escape(csv)+'将打破html的单引号字符串,并在href链接中插入转义后的csv。 - Dustin Graham

15

尝试以下示例:

示例1:

JsonArray = [{
    "AccountNumber": "1234",
    "AccountName": "abc",
    "port": "All",
    "source": "sg-a78c04f8"

}, {
    "Account Number": "1234",
    "Account Name": "abc",
    "port": 22,
    "source": "0.0.0.0/0",
}]

JsonFields = ["Account Number","Account Name","port","source"]

function JsonToCSV(){
    var csvStr = JsonFields.join(",") + "\n";

    JsonArray.forEach(element => {
        AccountNumber = element.AccountNumber;
        AccountName   = element.AccountName;
        port          = element.port
        source        = element.source

        csvStr += AccountNumber + ',' + AccountName + ','  + port + ',' + source + "\n";
        })
        return csvStr;
}

您可以使用以下代码下载CSV文件:

function downloadCSV(csvStr) {

    var hiddenElement = document.createElement('a');
    hiddenElement.href = 'data:text/csv;charset=utf-8,' + encodeURI(csvStr);
    hiddenElement.target = '_blank';
    hiddenElement.download = 'output.csv';
    hiddenElement.click();
}

有没有想过如何修改“downloadCSV”函数以支持西班牙字符? - Dean
怎样使用Excel文件来做这个? - Brad Ahrens

8

我想为以后的人们添加一些代码,因为我尝试将JSON导出到CSV文档并下载。

我使用 $.getJSON 从外部页面拉取JSON数据,但如果您有一个基本数组,可以直接使用它。

这里使用Christian Landgren 的代码来创建CSV数据。

$(document).ready(function() {
    var JSONData = $.getJSON("GetJsonData.php", function(data) {
        var items = data;
        const replacer = (key, value) => value === null ? '' : value; // specify how you want to handle null values here
        const header = Object.keys(items[0]);
        let csv = items.map(row => header.map(fieldName => JSON.stringify(row[fieldName], replacer)).join(','));
        csv.unshift(header.join(','));
        csv = csv.join('\r\n');

        //Download the file as CSV
        var downloadLink = document.createElement("a");
        var blob = new Blob(["\ufeff", csv]);
        var url = URL.createObjectURL(blob);
        downloadLink.href = url;
        downloadLink.download = "DataDump.csv";  //Name the file here
        document.body.appendChild(downloadLink);
        downloadLink.click();
        document.body.removeChild(downloadLink);
    });
});

编辑:值得注意的是,JSON.stringify会通过添加\"来转义引号中的引号。 如果您在Excel中查看CSV文件,则不喜欢这样的转义字符。
您可以在JSON.stringify(row [fieldName],replacer)的末尾添加 .replace(/ \\" / g,'""'),以在Excel中正确显示它(这将用"" 替换\",这是Excel所偏爱的)。
完整行:JSON.stringify(row [fieldName],replacer).replace(/ \\" / g,'""')

7

一个用于简单 JSON 的一行函数(带有静态标题)

假设 arr 是一个 JSON 数组,您还可以将第一个字符串替换为以逗号分隔的标题,以 \n 结尾

arr.reduce((acc, curr) => (`${acc}${Object.values(curr).join(",")}\n`), "")

或者使用之前提到的window.open函数

window.open(`data:text/csv;charset=utf-8,${arr.reduce((acc, curr) => (`${acc}${Object.values(curr).join(",")}\n`), "")}`)

您还应考虑对字符串进行转义或替换逗号以避免出现额外的单元格。

0
如果您的数据来自SQL数据库,则所有行应具有相同的结构,但如果来自NoSQL数据库,则可能难以使用标准答案。我针对这种情况详细介绍了JSON2CSV。 JSON数据示例
  [ {"meal":2387,"food":"beaf"},
    {"meal":2387,"food":"apple","peeled":"yes", "speed":"fast" },
    {"meal":2387,"food":"pear", "speed":"slow", "peeled":"yes" } ]

答案

"meal","food","peeled","speed"
"2387","beaf","",""
"2387","apple","yes","fast"
"2387","pear","yes","slow"

为简单起见,使用头文件和双引号的代码。

function JSON2CSV(objArray) {
  var array = typeof objArray != 'object' ? JSON.parse(objArray) : objArray;

  var str = '';
  var line = '';

  // get all distinct keys      
  let titles = [];
  for (var i = 0; i < array.length; i++) {
    let obj = array[i];
    Object.entries(obj).forEach(([key,value])=>{
      //console.log('key=', key, "   val=", value );
      if (titles.includes(key) ) {
        // console.log (key , 'exists');
        null;
      }
      else {
        titles.push(key);
      }
    })
  }
  let htext =  '"' + titles.join('","') + '"';
  console.log('header:', htext);
  // add to str
  str += htext + '\r\n';
  //
  // lines
  for (var i = 0; i < array.length; i++) {
    var line = '';
    // get values by header order
    for (var j = 0; j < titles.length; j++) {
      // match keys with current header
      let obj = array[i];
      let keyfound = 0;    
      // each key/value pair
      Object.entries(obj).forEach(([key,value])=>{
        if (key == titles[j]) {
          // console.log('equal tit=', titles[j] , ' e key ', key ); // matched key with header
          line += ',"' + value +  '"';
          keyfound = 1; 
          return false;
        }

      })
      if (keyfound == 0) {
        line += ',"'  +  '"';   // add null value for this key
      } // end loop of header values

    }

    str += line.slice(1) + '\r\n';
  }
  return str;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接