Search code examples
javascriptjsonnode.jsexceljs-xlsx

Output JSON to multiple lines with js-xlsx


I follow one of the solutions from here. The solution logs out to the console well, but I don't know how to save so it looks easy to read to .json file. I've tried using File System module to record the output to a .json. I don't know how to make it print all in multiple lines. It comes out all in one line.

var fs = require('fs');
var XLSX = require('xlsx');
var workbook = XLSX.readFile('test.xlsx');
var sheet_name_list = workbook.SheetNames;
sheet_name_list.forEach(function(y) {
    var worksheet = workbook.Sheets[y];
    var headers = {};
    var data = [];
    for(z in worksheet) {
        if(z[0] === '!') continue;
        //parse out the column, row, and value
        var col = z.substring(0,1);
        var row = parseInt(z.substring(1));
        var value = worksheet[z].v;

        //store header names
        if(row == 1) {
            headers[col] = value;
            continue;
        }

        if(!data[row]) data[row]={};
        data[row][headers[col]] = value;
    }
    //drop those first two rows which are empty
    data.shift();
    data.shift();
    //console.log(data);
    fs.writeFileSync("new.json", JSON.stringify(data), function(err) {
        if(err) {
            return console.log(err);
        }
    }); 
});

output of new.json

[{"key":"AprilA45","Food":"Sandwich","yr":2017,"mo":"April" ...

Solution

  • You can achieve this by using the additional arguments to the stringify method, specifically the space parameter:

    A String or Number object that's used to insert white space into the output JSON string for readability purposes. If this is a Number, it indicates the number of space characters to use as white space; this number is capped at 10 (if it is greater, the value is just 10). Values less than 1 indicate that no space should be used. If this is a String, the string (or the first 10 characters of the string, if it's longer than that) is used as white space. If this parameter is not provided (or is null), no white space is used.

    Here's a browser based example that shows what you want - first div is what you are currently getting; second div is what you want:

    let data = {"foo": ["bar", "baz"], "qux": "quux"};
    document.getElementById("first").innerHTML = "<pre>" + JSON.stringify(data) + "</pre>";
    document.getElementById("second").innerHTML = "<pre>" + JSON.stringify(data, null, 2) + "</pre>";
    <div id="first"></div>
    <div id="second"></div>

    So your code would be:

    fs.writeFileSync("new.json", JSON.stringify(data, null, 2), function(err) {
        if(err) {
            return console.log(err);
        }
    });