React ant table 用 XLSX 导出excel文件

近期做了一个react ant design 的table转换成excel 的功能 总结下

首先我们会自己定义下 antdesign 的table的columns其中有可能有多语言或者是render方法的转换显示(比如说加特殊符号或者属性的code转换成对应的显示名称)都可以应用上

比如

   const columns = [{
                title: 'Qty',
                dataIndex: 'quantity',
                key: 'quantity'
            }, {
                title: intl.get("totaldiscount").d('Total Discount Price'),
                dataIndex: 'price',
                key: 'price',
                render: text => {
                    var msg = text
                    switch (text) {
                        case "":
                            ''
                            break;
                        default:
                            msg => "¥" + msg
                            break;
                    }
                    return msg
                }
            }]
const data=[{qty:1,
price;10},{qty:2,price;20}]
  exportExcel([
            {
                blocks: [
                    { headers:columns, data:data },
                ], sheetName: "销售数据sheet"
            },
        ], "统计报表")

 

添加一个文件写exportExcel的function

支持同时生成多个sheet 

 

  1 import XLSX from 'xlsx';
  2 import { message } from 'antd';
  3 import { isBlank } from './PubUtils'
  4 
  5 //exportExcel  sheets=[blocks:[{headers:[],data:[]}],sheetName:""}]
  6 // fileName =""
  7 function exportExcel(sheets, fileName = 'dowloadFile') {
  8     if (sheets.length <= 0) {
  9         message.error("no data download")
 10         return
 11     }
 12  13     const sheetsArr = sheets.map(sheet => {
 14         let Count = 1
 15         let colsWidth = []
 16         let sheetOutPut = {}
 17          18         sheet.blocks.map(
 19             block => {
 20                 if (block.headers.length <= 0) {
 21                     message.error("no data download")
 22                     return
 23                 }
 24                 const blockHeaders = block.headers.filter(item => !item.excelHidden)
 25                 const _headers = blockHeaders
 26                     .map((item, i) => Object.assign({}, { key: item.key, title: item.title, position: getPostition(i) + Count }))
 27                     .reduce((prev, next) => Object.assign({}, prev, { [next.position]: { key: next.key, v: next.title } }), {});
 28                 console.log("_headers==", _headers)
 29                 Count++
 30                 let dataArr = [], _data = {}
 31                 //有数据时进行处理
 32                 if (block.data && block.data.length > 0) {
 33                     dataArr = block.data
 34                         .map((item, i) => blockHeaders.map((head, j) => {
 35                             let content = ""
 36                             let position = getPostition(j) + (i + Count)
 37                             if (head.excelRender) {
 38                                 content = head.excelRender(item[head.dataIndex], item, i)
 39                             } else if (head.render) {
 40                                 content = head.render(item[head.dataIndex], item, i)
 41                             } else {
 42                                 content = item[head.dataIndex]
 43                             }
 44                             content = isBlank(content) ? "" : content
 45                             // 转换成 worksheet 需要的结构
 46                             _data[position] = { v: content }
 47                             return { content, position }
 48                         }
 49                         ))
 50                 }
 51                 colsWidth = getColWidth(colsWidth, block.headers, dataArr)
 52                 Count += dataArr.length + 1
 53                 // 合并 headers 和 data
 54                 sheetOutPut = Object.assign({}, sheetOutPut, _headers, _data);
 55             }
 56         )
 57         if (colsWidth.length <= 0) {
 58             message.error("no data download")
 59             return Object.assign(
 60                 { sheetName: sheet.sheetName },
 61             )
 62         }
 63         // 计算出范围 ,["A1",..., "H2"]
 64         const ref = `A1:${getPostition(colsWidth.length - 1) + '' + Count}`;
 65         return Object.assign(
 66             { sheetName: sheet.sheetName },
 67             sheetOutPut,
 68             {
 69                 '!ref': ref,
 70                 '!cols': colsWidth,
 71             },
 72         )
 73     })
 74     const sheetNames = sheetsArr.map(sheet => sheet.sheetName)
 75     const wbSheets = sheetsArr.reduce((prev, next) =>
 76         Object.assign({}, prev, { [next.sheetName]: next }), {})
 77     // 构建 workbook 对象
 78     const wb = {
 79         SheetNames: sheetNames,
 80         Sheets: wbSheets,
 81     };
 82     // 导出 Excel
 83     XLSX.writeFile(wb, fileName + ".xlsx");
 84 }
 85 
 86 function getPostition(index) {
 87     let result = String.fromCharCode(65 + parseInt(index % 26))
 88     let value = index / 26
 89     while (value >= 1) {
 90         value = value - 1
 91         result = String.fromCharCode(65 + parseInt(value % 26)) + result
 92         value = parseInt(value / 26)
 93     }
 94     return result
 95 }
 96 function getColWidth(preColWidth, headers, dataArr) {
 97     const allWch = [headers,].concat(dataArr).map(item => item.map(val => {
 98         let value = val.title || val.content || ""
 99         let length = 10
100         /*先判断是否为null/undefined*/
101         if (value) {
102             /*再判断是否为中文*/
103             if (value.toString().charCodeAt(0) > 255) {
104                 length = value.toString().length * 2
105             } else {
106                 length = value.toString().length
107             }
108         }
109         return {
110             'wch': length < 40 ? length : 40
111         };
112     }))
113     if (preColWidth.length < allWch[0].length) {
114         preColWidth = preColWidth.concat(allWch[0].slice(preColWidth.length))
115     }
116     let colWidth = preColWidth
117     for (let i = 0; i < allWch.length; i++) {
118         for (let j = 0; j < allWch[i].length; j++) {
119             if (colWidth[j]['wch'] < allWch[i][j]['wch']) {
120                 colWidth[j]['wch'] = allWch[i][j]['wch'];
121             }
122         }
123     }
124     return colWidth
125 }
126 export default exportExcel;

 

 

 
posted @ 2019-09-27 17:17  少年工藤  阅读(1042)  评论(0编辑  收藏  举报