Search code examples
jsonexport-to-csv

How do i convert this json file to csv


I have this JSON which I want to convert to CSV, I have to use online tools for converting it but its not converting in proper CSV format according to the JSON format , but my JSON format is not in one layer, here is what I'm saying

because after converting into proper CSV i have to add some data and want to convert back to JSON like the original but with additional data so I can upload it on firebase


Solution

  • I suppose the first layer in the JSON is the first header name. The second layer has the value from 1st header as key and the other headers/values as value. This format is probably called "Hashed CSV". The format is something like below in Typescript:

    type HashedCsv = {
      [header1: string]: {
        [value1: string]: {
          [otherHeader: string]: string
        }
      }
    }
    

    So, to convert to CSV and from CSV you just need to have this type above in mind.

    Below is a code snippet in JavaScript to convert the JSON to CSV. You can test it here on StackOverflow by clicking Run code snippet or with even with NodeJS.

    function jsonToCsv (/** @type {{[header1: string]: {[value1: string]: {[otherHeader: string]: string}}}} */ json) {
        // The first layer is the first header name
        const header1 = Object.keys(json)[0]
        const values = json[header1]
        // In the 2nd layer are the other header names
        const otherHeaders = Object.keys(Object.values(values)[0])
        const headers = [header1, ...otherHeaders]
    
        /** @type {string[]} */
        const csvValues = []
        for (const [value1, otherValues] of Object.entries(values)) {
            csvValues.push([
                value1,
                // Escape commas and quotes
                ...otherHeaders.map(header => /[,"]/g.test(otherValues[header])
                    ? `"${otherValues[header].replaceAll('"', '""')}"`
                    : otherValues[header])
            ].join(','))
        }
    
        return [
            headers.join(','),
            ...csvValues
        ].join('\n')
    }
    
    const json = loadJson()
    const csv = jsonToCsv(json)
    console.log(csv)
    
    
    // Loads the JSON. It could be a file or from memory like below
    function loadJson () {
        return {
            "Quotes": {
                "q1": {
                    "title": "The unexamined life is not worth living – Socrates"
                },
                "q2": {
                    "title": "Whereof one cannot speak, thereof one must be silent – Ludwig Wittgenstein"
                },
                "q3": {
                    "title": "Entities should not be multiplied unnecessarily – William of Ockham"
                },
                "q4": {
                    "title": "The mind is furnished with ideas by experience alone – John Locke"
                },
                "q5": {
                    "title": "We are too weak to discover the truth by reason alone – St. Augustine"
                },
                "q6": {
                    "title": "Man is the measure of all things – Protagoras"
                },
                "q7": {
                    "title": "Everything that exists is born for no reason, carries on living through weakness, and dies by accident – Jean-Paul Sartre"
                },
                "q8": {
                    "title": "To do as one would be done by, and to love one's neighbor as oneself, constitute the ideal perfection of utilitarian morality – John Stuart Mill"
                },
                "q9": {
                    "title": "Good and evil, reward and punishment, are the only motives to a rational creature – John Locke"
                }
            }
        }
    }

    PS: Notice that I've stripped the JSON a bit.