點燈坊

失くすものさえない今が強くなるチャンスよ

How to Create CSV File and Download it Automatically ?

Sam Xiao's Avatar 2021-12-09

We can create a CSV file and download it automatically without any packages.

Version

Vue 3.2

Download CSV

cvs000

Click the button to download CSV automatically.

<script setup>
import { pipe, map, join, values, head, keys, concat, __, converge } from 'ramda'

let data = [
  { title: 'FP in JavaScript', price: 100 },
  { title: 'Programming Haskell', price: 200 },
  { title: 'Speaking JavaScript', price: 300 }
]

let header = pipe (
  head,
  keys,
  join (','),
  concat(__, '\n')
)

let objToStr = pipe (
  values,
  join (',')
)

let body = pipe (
  map (objToStr),
  join ('\n')
)

let arrToCSV = converge (
  concat, [header, body]
)

let onClick = () => {
  let csv = arrToCSV (data)

  let anchor = document.createElement ('a')
  anchor.href = `data:text/csv;charset=utf-8,${encodeURIComponent (csv)}`
  anchor.target = '_blank'
  anchor.download = 'data.csv'
  anchor.click ()
}
</script>

<template>
  <button @click="onClick">Download CSV</button>
</template>

Line 4

let data = [
  { title: 'FP in JavaScript', price: 100 },
  { title: 'Programming Haskell', price: 200 },
  { title: 'Speaking JavaScript', price: 300 }
]

Data is Object Array, and we want to convert it to a CSV file first.

Line 10

let header = pipe (
  head,
  keys,
  join (','),
  concat (__, '\n')
)

Use pipe to compose function for header of CSV :

  • head : get the first element of Array to create the header. It is an Object
  • keys : get all keys from the Object as Array
  • join (',') : convert Array to String separated by ,
  • concat (__, '\n') : add Line Feed at the end of String

Line 22

let body = pipe (
  map (objToStr),
  join ('\n')
)

Use pipe to compose function for the body of CSV :

  • map (objToStr):map each Object converted to String
  • join ('\n'):convert Array to String separated by \n

Line 17

let objToStr = pipe (
  values,
  join (',')
)

Use pipe to compose function to convert Object to String separated by ,. This is the most critical point to solve this problem :

  • values:get all values from the Object as Array
  • join (','):convert Array to String separated by ,

Line 27

let arrToCSV = converge (
  concat, [header, body]
)

Use converge to compose function to merge header and body to CSV :

  • concat:merge header and body

Line 31

let onClick = () => {
  let csv = arrToCSV (data)

  let anchor = document.createElement ('a')
  anchor.href = `data:text/csv;charset=utf-8,${encodeURIComponent (csv)}`
  anchor.target = '_blank'
  anchor.download = 'data.csv'
  anchor.click ()
}

Create CSV file and download it automatically :

  • Use arrToCSV to convert Object Array to CSV
  • Create <a> on the fly and download CSV automatically

Conclusion

  • Object Array to CSV is essentially a series of transformations. It is an excellent time to use Function Pipeline
  • Downloading Automatically can be implemented by creating <a> on the fly