點燈坊

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

如何將 Object Array 轉 CSV 並下載 ?

Sam Xiao's Avatar 2024-04-23

雖然可以從 Server 端直接處理 CSV 下載,但若 CSV 內必須處理多國語言,則必須將 Object Array 先下載到 Browser,然後再轉成 CSV 下載。

Version

ECMAScript 2015

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>HTML Lab</title>
  </head>
  <body>
    <button id="download-csv">Download CSV</button>
  </body>
  <script>
    let covertToCSV = arr => {
      let headers = Object.keys(arr[0])
      let rows = arr.map(item => headers.map(header => item[header]))
      let headerRow = headers.join(',')
      let csvRows = [headerRow, ...rows.map(row => row.join(','))]

      return csvRows.join('\n')
    }

    let data = [
      { name: 'John', age: 24, city: '紐約' },
      { name: 'Jane', age: 23, city: '芝加哥' },
      { name: 'Jim', age: 25, city: '洛杉磯' },
    ]

    let downloadCSV = document.querySelector('#download-csv')
    downloadCSV.addEventListener('click', () => {
      let csv = covertToCSV(data)

      let blobUrl = URL.createObjectURL(new Blob(['\uFEFF' + csv]))
      let anchor = document.createElement('a')
      anchor.href = blobUrl
      anchor.target = '_blank'
      anchor.download = 'export_data.csv'
      anchor.click()
    })
  </script>
</html>

Line 21

let data = [
  { name: 'John', age: 24, city: '紐約' },
  { name: 'Jane', age: 23, city: '芝加哥' },
  { name: 'Jim', age: 25, city: '洛杉磯' },
]
  • 資料必須是 Object Array 形式,資料可以包含中文

Line 12

let covertToCSV = arr => {
  let headers = Object.keys(arr[0])
  let rows = arr.map(item => headers.map(header => item[header]))
  let headerRow = headers.join(',')
  let csvRows = [headerRow, ...rows.map(row => row.join(','))]

  return csvRows.join('\n')
}
  • 將 Object Array 轉成 CSV

Line 29

let csv = covertToCSV(data)

let blobUrl = URL.createObjectURL(new Blob(['\uFEFF' + csv]))
let anchor = document.createElement('a')
anchor.href = blobUrl
anchor.target = '_blank'
anchor.download = 'export_data.csv'
anchor.click()
  • 將 CSV 自動下載

Line 31

let blobUrl = URL.createObjectURL(new Blob(['\uFEFF' + csv]))
  • 加入 BOM 讓 Excel 可成功開啟

Conclusion

  • 傳統建立 CSV 方法無法結解 Excel 開啟會有亂碼問題,唯有加入 BOM 之後才能解決