[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$frDFQQ4nj0nZTXuZWoiD06AZWvEY5OePpMLB2XIupUuc":3},{"code":4,"message":5,"data":6},200,"成功",{"id":7,"createdAt":8,"title":9,"content":10,"summary":11,"image":12,"uid":13,"user":14,"categoryId":21,"category":22,"subCategoryId":24,"subCategory":25,"comments":27,"status":17,"reason":28,"notice":28,"visitCount":29,"commentCount":30,"keywords":31},140,"2024-11-27T11:41:32.455Z","前端开发-如何生成并导出xlsx或者csv文件","在前端开发中，尤其是一些管理后台的开发项目中，经常有需要生成并导出表格的场景。最常见的表格格式莫过于xlsx和csv这两种格式的excel文件。\n\n这种场景有两种实践：\n1. 服务端生成了excel表格，将文件uri网络地址通过接口传给前端，前端使用`window.location.href`或者`window.open`等方法使用跳转下载这个uri对应的表格文件。\n2. 前端根据已有的数据，自行生成excel表格，实现自动下载文件。\n\n第1个实践对于前端来说是比较方便的，今天我们介绍第2个实践。介绍的包含2种格式（xlsx、csv）的文件生成和下载，推荐`xlsx`格式的excel。\n\n## 一、xlsx格式excel文件生成和下载\n这种方式通过使用前端库`xlsx`来实现：\n```package.json\n...\n\"dependencies\": {\n  ...\n  \"xlsx\": \"^0.18.5\",\n  ...\n}\n...\n```\n封装代码：\n```xlsxFileHandle.ts\nimport * as XLSX from 'xlsx';\n\nexport interface excelType {\n  json: object;\n  name: string;\n  titleArr: string[];\n  sheetName: string;\n}\n\n/**\n * 导出成xlsx文件\n * @param params 传入的数据格式\n */\nexport const exportExcel = (params: excelType) => {\n    const keyArray = [];\n    let data = [];\n    const getLength = function (obj: object) {\n        let count = 0;\n        for (const i in obj) {\n          if (Object.prototype.hasOwnProperty.call(obj, i)) {\n            count++;\n          }\n        }\n        return count;\n    };\n\t\n    for (const key1 in params.json) {\n      if (Object.prototype.hasOwnProperty.call(params.json, key1)) {\n        const element = (params.json as { [key: string]: object })[key1];\n        const rowDataArray = [];\n        for (const key2 in element) {\n          if (Object.prototype.hasOwnProperty.call(element, key2)) {\n            const element2 = (element as { [key: string]: object })[key2];\n            rowDataArray.push(element2);\n            if (keyArray.length \u003C getLength(element)) {\n              keyArray.push(key2);\n            }\n          }\n        }\n        data.push(rowDataArray);\n      }\n    }\n    data.splice(0, 0, params.titleArr as any);\n    data = data.filter(e => e.length > 0)\n\n    console.log(data);\n    let ws = XLSX.utils.aoa_to_sheet(data);\n    let wb = XLSX.utils.book_new();\n    // 隐藏英文字段表头\n    const wsrows = [{ hidden: false }];\n      /* 设置worksheet每列的最大宽度 */\n      const colWidth = data.filter(e => e.length > 0).map((row) =>\n        row.map((val) => {\n          /* 先判断是否为null/undefined */\n          if (val == null) {\n            return {\n              wch: 20,\n            };\n          } else if (val.toString().charCodeAt(0) > 255) {\n            /* 再判断是否为中文 */\n            return {\n              wch: val.toString().length * 2,\n            };\n          } else {\n            return {\n              wch: val.toString().length*2,\n            };\n          }\n        })\n      );\n      /* 以第一行为初始值 */\n      const result = colWidth[1];\n      for (let i = 1; i \u003C colWidth.length; i++) {\n        for (let j = 0; j \u003C colWidth[i].length; j++) {\n          if (result[j].wch \u003C colWidth[i][j].wch) {\n            result[j].wch = colWidth[i][j].wch;\n          }\n        }\n      }\n      ws['!cols'] = result;\n      ws['!rows'] = wsrows; // ws - worksheet\n      XLSX.utils.book_append_sheet(wb, ws, params.sheetName);\n      /* generate file and send to client */\n      XLSX.writeFile(wb, `${params.name}.xlsx`);\n};\n\n```\n使用实例代码：\n```payExport.ts\nimport { exportExcel } from \"../xlsxFileHandle\"\n\n/**\n * 导出成xlsx文件\n */\nexport const ExportForXlsx = (batch_id: number, valueList: Array\u003CxxxListItem>) => {\n    const titleList = [\n        \"ID\",\n        \"订单ID\",\n        \"姓\",\n        \"名\",\n        \"收款人名字\",\n        \"电话\",\n        \"账号号码\",\n        \"银行名字\",\n        \"账号名字\",\n        \"收款金额\",\n        \"选填，附言\",\n        \"扣款金额\",\n        \"汇率\",\n        \"手续费$\",\n        \"创建时间\",\n        \"完成时间\",\n        \"订单状态\",\n    ]\n    const getStatusDesc = (status: number) => {\n        if (status == 1) {\n            return '待付款'\n        }\n        if (status == 2) {\n            return '失败'\n        }\n        if (status == 3) {\n            return '成功'\n        }\n        if (status == 4) {\n            return '处理中'\n        }\n        if (status == 5) {\n            return '失败-系统'\n        }\n        return '未知'\n    }\n    const newValueList = valueList.map(e => {\n        return {\n            \"ID\" : e.payee_id + '',\n            \"订单ID\": e.order_id + '',\n            \"姓\": e.last_name + '',\n            \"名\": e.first_name + '',\n            \"收款人名字\": e.payee_name + '',\n            \"电话\": e.phone_number + '',\n            \"账号号码\": e.account_id + '',\n            \"银行名字\": e.back_name + '',\n            \"账号名字\": e.bank_account_number + '',\n            \"收款金额\": e.receive_amount + '',\n            \"选填，附言\": e.remark + '',\n            \"扣款金额\": e.buckle_amount + '',\n            \"汇率\": e.exchange_rate + '',\n            \"手续费$\": e.handling_fee + '',\n            \"创建时间\": e.create_time + '',\n            \"完成时间\": (e.complete_time > 0 ? moment(e.complete_time).format('YYYY-MM-DD HH:mm:ss') : e.complete_time) + '',\n            \"订单状态\": getStatusDesc(e.status) + ''\n        }\n    })\n    const tableName = '支付-' + batch_id //表名\n    exportExcel({\n        json: newValueList,//数据\n        name: tableName, // 表名\n        titleArr: titleList,//表头\n        sheetName: batch_id + '',//页签\n    })\n}\n```\n以上方法得到的效果：\n![导出excel](https://image.xinwei.ltd/41732707449352.png)\n\n## 二、csv格式excel文件生成和下载\n不使用任何库，而是将数据合成字符串。\n封装代码：\n```csvFile.ts\n/**\n * 导出成.csv格式的表格\n * @param titleList 比如：['ID', '姓名', '年龄']\n * @param valueList 比如：[ [1, '张三', 28], [2, '李四', 22] ]\n */\nexport const extractCsvFileFromData = (titleList: Array\u003Cstring>, valueList: Array\u003Cany>) => {\n    const totalList = [titleList, ...valueList]\n    // 将数据转换为CSV格式的字符串  \n    let csvContent = \"data:text/csv;charset=utf-8,\";  \n    totalList.forEach((row, index) => {  \n      if (index > 0) {  \n        csvContent += \"\\n\";  \n      }  \n      csvContent += row.join(\",\");  \n    });  \n\n    // 创建一个可下载的链接  \n    const encodedUri = encodeURI(csvContent);  \n    const link = document.createElement(\"a\");  \n    link.setAttribute(\"href\", encodedUri);  \n    link.setAttribute(\"download\", \"数据.csv\");  \n    document.body.appendChild(link); // 需要添加到body  \n    link.click();\n}\n```\n使用示例代码：\n```pay.ts\nimport moment from \"moment\"\n\n/**\n * 将明细列表，生成csv文件\n * @param valueList 明细列表数据\n */\nexport const GenerateCSVFileFrom = (valueList: Array\u003CxxxListItem>) => {\n    const titleList = [\n        \"ID\",\n        \"订单ID\",\n        \"姓\",\n        \"名\",\n        \"收款人名字\",\n        \"电话\",\n        \"账号号码\",\n        \"银行名字\",\n        \"账号名字\",\n        \"收款金额\",\n        \"选填，附言\",\n        \"扣款金额\",\n        \"汇率\",\n        \"手续费$\",\n        \"创建时间\",\n        \"完成时间\",\n        \"订单状态\",\n    ]\n\n    const getStatusDesc = (status: number) => {\n        if (status == 1) {\n            return '待付款'\n        }\n        if (status == 2) {\n            return '失败'\n        }\n        if (status == 3) {\n            return '成功'\n        }\n        if (status == 4) {\n            return '处理中'\n        }\n        if (status == 5) {\n            return '失败-系统'\n        }\n        return '未知'\n    }\n    \n    const newValueList = valueList.map(e => {\n        return [\n            e.payee_id + '', e.order_id + '', e.last_name + '', e.first_name + '',\n            e.payee_name + '', e.phone_number + '', e.account_id + '', e.back_name + '',\n            e.bank_account_number + '', e.receive_amount + '', e.remark + '', e.buckle_amount + '',\n            e.exchange_rate + '', e.handling_fee + '', e.create_time + '', (e.complete_time > 0 ? moment(e.complete_time).utcOffset(-5).format('YYYY-MM-DD HH:mm:ss') : e.complete_time) + '',\n            getStatusDesc(e.status) + ''\n        ]\n    })\n   \n    extractCsvFileFromData(titleList, newValueList)\n}\n```\n\n以上就是在前端开发中，生成和导出xlsx和csv格式的excel文件的简单实践，希望对大家有帮助。\n","今天介绍一下如何在前端开发中，实现生成xlsx或者csv文件的方法和步骤，算是记录一下，供大家参考。","https://image.xinwei.ltd/41732707449352.png",499668042977349,{"phone":15,"userId":13,"nickName":16,"vipType":17,"avatar":18,"sign":19,"createdAt":20},"13121171998","全栈老韩",1,"https://image.xinwei.ltd/images/IMG_5430.JPG","全栈工程师，擅长iOS App开发、前端（vue、react、nuxt、小程序&Taro）开发、Flutter、React Native、后端（midwayjs、golang、express、koa）开发、docker容器、seo优化等。","2024-01-01T16:14:30.305Z",2,{"id":21,"name":23},"IT技术",32,{"id":24,"name":26,"parentId":21},"前端",[],"",1344,0,"xlsx,vue xlsx,csv xlsx,vue csv,vue生成csv,vue生成xlsx,导出xlsx,下载excel,下载xlsx,下载csv"]