前端将json数据导出为excel

网上找了几种方法,

1、导出为xls文件,高版本的excel打开会提示类似兼容问题

下面文档可以参考,实测可用

https://blog.csdn.net/qq_34623560/article/details/79928248

 

2、导出为xlsx文件,低版本的excel会打不开,但是考虑到2007的excel用的比较少了,所以选了这个文件格式

网上找到的几个帖子,内容都一样,代码都有点问题,导出文件只有列名,没有数据,而且rowLength感觉没什么用,我也去掉了,帖子如下(xls的没试,xlsx和csv都有问题)

https://blog.csdn.net/qq_35493664/article/details/88896638

 

3、我修改了一下,可以参考(csv格式的也可以参考我修改的地方进行修改,估计问题差不多)

jsonData就是json数据

  1 import * as XLSX from 'xlsx'
  2 // JSONData为导出的json数据,fileName为导出的文件名,title为导出的第一行标题,filter为过滤字段
  3 export function JSONToExcelConvertor(JSONData, FileName, title, filter) {
  4   if (!JSONData) { return }
  5   // 转化json为object
  6   var arrData = typeof JSONData !== 'object' ? JSON.parse(JSONData) : JSONData
  7  
  8   var excel = '<table id="expoetTable">'
  9  
 10   // 设置表头
 11   var row = '<tr>'
 12   if (title) {
 13     // 使用标题项
 14     for (var i in title) {
 15       row += "<th align='center'>" + title[i] + '</th>' // 将标题新增到row中
 16     }
 17   } else {
 18     // 不使用标题项
 19     for (var i in arrData[0]) {
 20       row += "<th align='center'>" + i + '</th>'
 21     }
 22   }
 23  
 24   excel += row + '</tr>'
 25   // 设置数据
 26   for (var i = 0; i < arrData.length; i++) {
 27     if (i === arrData.length - 1) {
 28       var row = '<tr>'
 29     } else {
 30       var row = ''
 31     }
 32     for (var index in arrData[i]) {
 33       console.log('index', index)
 34       // 判断是否有过滤行
 35       if (filter) {
 36         var value = ''
 37         console.log('filter.indexOf(index)', filter.indexOf(index))
 38         if (filter.indexOf(index) === -1) { // 过滤掉符合关键字的数据
 39           var value = arrData[i][index] == null ? '' : arrData[i][index]
 40           row += '<td>' + value + '</td>'
 41         } 
 42       } else {
 43         // 不过滤的逻辑
 44         var value = arrData[i][index] == null ? '' : arrData[i][index]
 45         row += "<td align='center'>" + value + '</td>'
 46       } 
 47     }
 48     excel += row + '</tr>'
 49   }
 50  
 51   excel += '</table>'
 52   var objE = document.createElement('div') // 因为我们这里的数据是string格式的,但是js-xlsx需要dom格式,则先新建一个div然后把数据加入到innerHTML中,在传childNodes[0]即使dom格式的数据
 53   objE.innerHTML = excel
 54   var sheet = XLSX.utils.table_to_sheet(objE.childNodes[0], { raw: true })// 将一个table对象转换成一个sheet对象,raw为true的作用是把数字当成string,身份证不转换成科学计数法
 55   openDownloadDialog(sheet2blob(sheet, FileName), FileName + '.xlsx')
 56 }
 57  
 58 // 将一个sheet转成最终的excel文件的blob对象,然后利用URL.createObjectURL下载
 59 function sheet2blob(sheet, sheetName) {
 60   sheetName = sheetName || 'sheet1' // 不存在sheetName时使用sheet1代替
 61   var workbook = {
 62     SheetNames: [sheetName],
 63     Sheets: {}
 64   }
 65   workbook.Sheets[sheetName] = sheet // 生成excel的配置项
 66   workbook.Sheets[sheetName]['!cols'] = [    //生成excel的列的宽度
 67                       { wch: 20 }, // 第一列
 68                       { wch: 40 }, // 第二列
 69                       { wch: 80 }  // 第三列
 70 ]
 71  
 72   var wopts = {
 73     bookType: 'xlsx', // 要生成的文件类型
 74     bookSST: false, // 是否生成Shared String Table,官方解释是,如果开启生成速度会下降,但在低版本IOS设备上有更好的兼容性
 75     type: 'binary' // 二进制格式
 76   }
 77   var wbout = XLSX.write(workbook, wopts)
 78   var blob = new Blob([s2ab(wbout)], {
 79     type: 'application/octet-stream'
 80   }) // 字符串转ArrayBuffer
 81   function s2ab(s) {
 82     var buf = new ArrayBuffer(s.length)
 83     var view = new Uint8Array(buf)
 84     for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF
 85     return buf
 86   }
 87   return blob
 88 }
 89 // 下载的方法
 90 function openDownloadDialog(url, saveName) {
 91   if (typeof url === 'object' && url instanceof Blob) {
 92     url = URL.createObjectURL(url) // 创建blob地址
 93   }
 94   var aLink = document.createElement('a')
 95   aLink.href = url
 96   aLink.download = saveName || '' // HTML5新增的属性,指定保存文件名,可以不要后缀,注意,file:///模式下不会生效
 97   var event
 98   if (window.MouseEvent) event = new MouseEvent('click')
 99   else {
100     event = document.createEvent('MouseEvents')
101     event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null)
102   }
103   aLink.dispatchEvent(event)
104 }
105  

 

我修改的部分主要是判断是否过滤的代码部分:

 

增加了一部分,定义文件的列的宽度的代码:

 

posted @ 2023-07-24 18:23  comeoncode  阅读(2324)  评论(0编辑  收藏  举报