web端导出csv文件

前言

导出文件,大部分方式还是服务端来处理的,通过服务端的方式生成文件,然后传递到客户端

但是,有时候可能就想使用web前端直接把页面上的内容导出来

前段时间做了一个多行多列导出页面的table表格,用的是a标签(支持firefox和Chrome)实现的(IE可以使用ActiveXObiect实现

忽视点

  • 如何分行,分列

    • 理论上,分列使用,号分割,分行用\n
    • 但是会出现列可以分开,但是不会换行的情况
    • 解决方法是,将生成的csv字符串使用encodeURIComponent编码
  • csv导出出现中文乱码(Excel打开)

    • 少了一个BOM头,\ufeff,加上\ufeff BOM头,csv="\ufeff"+csv
    • 页面的charset需设置成UTF-8
  • a的download属性可以指定下载的文件名及后缀,但是Chrome执行的时候会有bug

    • 之前写的a.href = "data:text/csv;charset=utf-8,\ufeff"+str;Chrome不理会
    • 改成如下代码,使用Blob和URL来封装和转换,问题解决
      var blob = new Blob([csv],{
         type: 'text/csv,charset=UTF-8'
      })
      

    var csvUrl = window.URL.createObjectURL(blob)
    var a = document.createElement('a')
    a.href = csvUrl

导出报表源码

exportData(list) {
    let tableHeader = [{
       type: 'theme',
       name: '报表名称'
      },{...},...]
     let tableBody = []
     for (let item of list) {
        let object = {theme:'',...}
        object.theme = item.title.replace('{DATE}','')+'('+item.info+')'
         ...
         for (let to of item.to) {
           object.to += to + ";\n"
         }
         ...
        tableBody.push({
           theme : object.theme || '',
          ...
       })
    }  
    var csv = '\ufeff'
    var keys= []
    tableHeader.forEach(function(item){
       csv+='"'+item.name+'",'
       keys.push(item.type)
   })
   csv=csv.replace(/\,$/, '\n')
   tableBody.forEach(function(item){
      keys.forEach(function(key){
        csv+='"'+item[key] +'",'
     })
     csv=csv.replace(/\,$/, '\n')
  })
  csv=csv.replace(/"null"/g, '""') 
  var  blob=new Blob([csv],{
     type:'text/csv,charset=UTF-8'
  })
  var csvUrl=window.URL.createObjectURL(blob)
  var a=document.createElement('a')
  var now=newDate()
  function to2(num) {
     returnnum>9?num:'0'+num
  }
  a.download='报表信息导出'+now.getFullYear() +to2((now.getMonth() +1)) +to2(now.getDate()) 
  +to2(now.getHours()) +to2(now.getMinutes()) +to2(now.getSeconds()) +'.csv'
   a.href=csvUrl
   document.body.appendChild(a)
   a.click()
   document.body.removeChild(a)
 }

注:tableHead存放表头,tableBody存放表格内容
download设置下载的文件名
点击click是下载文件