简体   繁体   中英

Generate a csv file from a javascript array of objects

I know this is a question already answered but couldn't find the solution that works for me.

I've a HTML button that, when clicked, generate an array of objects in typescript(which basically javascript) and i want to generate a csv file that will be downloaded.

Here is the example of the javascript array of objects:

    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" }];

    // Loop the array of objects
for(let row = 0; row < items.length; row++){
    let keysAmount = Object.keys(items[row]).length
    let keysCounter = 0

    // If this is the first row, generate the headings
    if(row === 0){

       // Loop each property of the object
       for(let key in items[row]){

                           // This is to not add a comma at the last cell
                           // The '\n' adds a new line
           csv += key + (keysCounter+1 < keysAmount ? ',' : '\r\n' )
           keysCounter++
       }
    }else{
       for(let key in items[row]){
           csv += items[row][key] + (keysCounter+1 < keysAmount ? ',' : '\r\n' )
           keysCounter++
       }
    }

    keysCounter = 0
}
console.log(csv)

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

I tried this example code but in my case it create the csv file, but doesn't insert the csv string correctly in the csv file, the csv string is has rows of element separated by a comma and each row is determined by a new line, but here all the data of each row sits in one cell of the csv file, how can I make so that each value of each row sits in a different cell?

here is the csv string that it:

    name,color,size
Item 2,Green,X-Large
Item 3,Green,X-Large

CSV is just a file with each cell separated by a comma and each row separated by a new line. You want to name each column as the key of the object. If I understood correctly:

{ "name": "Item 1", "color": "Green", "size": "X-Large" }

Will be:

---------------------------
| name   | color |   size  |
---------------------------
| Item 1 | Green | X-Large |
---------------------------

UPDATE: This is the updated version.

So you can loop your array and generate the csv accordingly using the File API from HTML5:

let csv

// Loop the array of objects
for(let row = 0; row < items.length; row++){
    let keysAmount = Object.keys(items[row]).length
    let keysCounter = 0

    // If this is the first row, generate the headings
    if(row === 0){

       // Loop each property of the object
       for(let key in items[row]){

                           // This is to not add a comma at the last cell
                           // The '\r\n' adds a new line
           csv += key + (keysCounter+1 < keysAmount ? ',' : '\r\n' )
           keysCounter++
       }
    }else{
       for(let key in items[row]){
           csv += items[row][key] + (keysCounter+1 < keysAmount ? ',' : '\r\n' )
           keysCounter++
       }
    }

    keysCounter = 0
}

// Once we are done looping, download the .csv by creating a link
let link = document.createElement('a')
link.id = 'download-csv'
link.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(csv));
link.setAttribute('download', 'yourfiletextgoeshere.csv');
document.body.appendChild(link)
document.querySelector('#download-csv').click()

BTW If you are using TypeScript, then the last line document.querySelector('#download-csv').click() MUST be <HTMLElement>document.querySelector('#download-csv').click() Let me know if it worked for you.

Fiddle for TypeScript and javascript (it changes just the last line): https://jsfiddle.net/0p8revuh/4/

UPDATE: To see the file propertly formated in excel, a cell for each comma separated value, do the following:

  1. You will see your data in several rows. Just click on the 'A' column to select all the rows: 在此处输入图片说明

  2. Go to your excel and click on Data at the top: 在此处输入图片说明

  3. Click on Text to columns : 在此处输入图片说明

  4. Select delimited: 在此处输入图片说明

  5. Click on next and active comma : 在此处输入图片说明

  6. Click on next and finish . Now you should be able to see your data propertly formated.

It works! But the way of code looks more complex and not easily understandable. I think the following code might be a little bit clear.

Also, I notified we need to keep the object key properly example if we want all in the capital we need to keep the object name in the capital but the property of the object key I'm not like to be capital. Most of the time It should be lowercase.In this case, also this solution might be helpful.

  let csvText = '';

    data.forEach((row, ind) => {
      if (!ind) {
        return (csvText += `${[
          'STOCK',
          'MAXPAIN',
          'CASH RATE',
          'FUTURE RATE',
          'PE',
          'PE OI',
          'CE',
          'CE OI',
          'PC RATIO MAX',
          'PC RATIO TOTAL'
        ].join(',')}\r\n`);
      }

      const properValues = [row.stock, row.option, row.strike, 0, row.put, row.put_oi, row.call, row.call_oi, 0, 0];

      return (csvText += `${properValues.join(',')}\r\n`);
    });

    console.log(csvText);

Ensure that heading value and not heading value return like the same order; otherwise, it'll be petrified.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM