Vue、React实现excel导出功能(三种实现方式保姆级讲解)

第一种:后端返回文件流,前端转换并导出(常用,通常公司都是用这种方式)

第二种:纯后端导出(需要了解)

第三种:纯前端导出(不建议使用,数据处理放在前端会引发一些不必要的问题

一、实现效果:

二、以下是三种不同方式实现的详细步骤

1、后端返回文件流,前端转换后并导出
(1)添加导出按钮

代码如下:

<!-- 这里我用的是antdVue组件库,按照你当前项目使用的组件库更改一下组件标签即可 -->
<a-button @click="exportTable"><!-- DownloadOutlined 是从组件库中引入的icon图标 --><DownloadOutlined />导出
</a-button>
 (2)添加api接口,配置responseType为blob
// 出库明细导出
exportOutboundDetails(data){//这里需要跟后端对接导出接口用的什么路径和方法,params为调接口所传递的参数,//设置responseType: "blob"这一点很重要,否则会导致转换失败return request.get( "你的接口路径",{params: data,responseType: "blob"})
},
(3)添加点击事件导出excel
import { message } from 'ant-design-vue';
const exportTable = async()=> {// 调后端接口获取数据需要用的参数(根据接口文档传参)const params = {pageNum: 1,pageSize: 30,}const res = await api.exportOutboundDetails(params)// 使用从 API 返回的数据 res 创建一个新的 Blob 对象let blob = new Blob([res], {type: "application/octet-stream",});let filename = "自定义文件名称"+ '.xls'// 创建一个代表该 Blob 对象的 URL,这个 URL 可以用于在浏览器中引用该 Bloblet blobURL = window.URL.createObjectURL(blob);// 创建一个新的 <a> HTML 元素,用于触发下载let tempLink = document.createElement("a");tempLink.style.display = "none";tempLink.href = blobURL;// 设置 <a> 元素的 download 属性,这样当用户点击这个链接时,浏览器会开始下载数据,而不是导航到它tempLink.setAttribute("download", filename);//如果浏览器的 download 属性不被支持(在某些旧版或特定的浏览器中),则设置 target 属性为 "_blank",这样当用户点击链接时,它会在新的浏览器标签或窗口中打开if (typeof tempLink.download === "undefined") {tempLink.setAttribute("target", "_blank");}// 将这个 <a> 元素添加到文档的 body 中document.body.appendChild(tempLink);// 模拟用户点击这个 <a> 元素,从而触发下载tempLink.click();// 从文档的 body 中移除这个 <a> 元素document.body.removeChild(tempLink);// 释放之前创建的 Blob URL,避免内存泄漏window.URL.revokeObjectURL(blobURL);message.success('导出成功');
}
2、纯后端导出

后端通过flush下载,前端不需要做其他处理,只需要开一个空白页直接调接口即可(服务端接口会直接下载)

(1)添加导出按钮(页面布局是一样的,这里我就不加入代码了,直接拿上面的即可)
(2)添加点击事件导出excel
const activityId = 1
const exportTable = () => {// 获取当前环境下的url,其中包含协议、域名、端口(例:https://www.example.com:8080)const origin = window.location.origin;// 创建一个 a 标签const link = document.createElement('a');// '/pc/activity/exportList' 为后端给的接口地址,'?id='后拼接参数(根据接口文档决定参数是否需要传递)link.href = `${origin}/pc/activity/exportList?id=${activityId}`;// 触发点击事件 link.click();
};
3、纯前端导出

(这里以vue2+elementUI为例)

(1)下载并挂载VXETable
// 我使用的版本(先下载再引入):
// "vxe-table": "~1.12.5",
// "vxe-table-plugin-element": "~1.2.1",
import VXETable from 'vxe-table'
import 'vxe-table/lib/index.css'
import VXETablePluginElement from 'vxe-table-plugin-element'
import 'vxe-table-plugin-element/dist/style.css'// 将VXETable挂载到vue上
Vue.use(VXETable)
VXETable.use(VXETablePluginElement)
 (2)添加导出按钮
  <!-- vxe-grid 是一个基于 Vue.js 的表格组件库,用于构建复杂的数据表格。 --><!-- ref="countTable"  这是一个 Vue.js 的引用(ref)属性。通过它,我们可以在 Vue 组件的实例中通过 this.$refs.countTable 访问到这个 vxe-grid 组件实例,从而进行各种操作,如获取数据、修改配置等。 --><!-- :columns='countTableColumn' 是一个定义了表格列的对象数组放在了columns属性上。 --><!-- :data.sync="countTableData" 这里使用了 .sync 修饰符,它是 Vue.js 2.3.0+ 版本中引入的一个语法糖,用于双向绑定父子组件之间的某个 prop。这意味着,当 vxe-grid 组件内部的数据发生变化时,父组件的 countTableData 也会相应地更新,反之亦然。这样就可以轻松地在父组件中管理和操作表格数据。 --><div><a-button @click="exportData"> 导出 </a-button><vxe-grid ref="countTable" :columns='countTableColumn' :data.sync="countTableData"></vxe-grid>
</div>
(3)添加点击事件导出excel
// 下载这两个库,我使用的版本:"file-saver": "^2.0.2"和"xlsx": "^0.14.4"
import XLSX from 'xlsx';
import FileSaver from 'file-saver';// 表格列对象数据(这里我写的死数据用于测试),在data中进行定义
data() {return {countTableColumn:[{field:'category',title:'日期'},{field:'vf_small',title:'购物袋(小)'},{field:'vf_middle',title:'购物袋(中)'},{field:'vf_big',title:'购物袋(大)'}],countTableData: [],//表格数据};
},// getExportData方法用于准备导出表格数据。它选择所有行,提取选定行的数据,并根据列的配置信息创建一个适合导出的数据结构。
getExportData(isHead) {// 在当前 Vue 实例的方法中,找到 ref 为 countTable 的 vxe-grid 组件实例,并调用其 setAllSelection 方法以选中所有行。this.$refs.countTable.setAllSelection(true);// 在当前 Vue 实例的方法中,找到 ref 为 countTable 的 vxe-grid 组件实例,并调用其 getSelectRecords 方法以获取当前被选中的记录数据。let datas = this.$refs.countTable.getSelectRecords();// 下面的数据是我用来做了数据处理,可以根据需求处理,console.log打印一下值,其中field和title是我当前数据中具有的属性,并不是固定的哈~let columns = this.countTableColumn.filter(item => item.field)let headers = isHead ? [columns.map(item => item.title)] : []console.log("datas",datas)console.log("columns",columns)console.log("headers",headers)// 该方法返回一个数组,该数组由 headers 和另一个数组组成。这个另一个数组是通过将 datas 数组中的每一行映射到 columns 数组中的每一列来创建的。这实际上是将二维数据(表格的行和列)转换为一维数组,其中每一行都成为一个嵌套数组,每个嵌套数组中的元素对应于该行的各个列。return headers.concat(datas.map(row => {return columns.map(column => {return row[column.field]})}))
},
// 点击导出
exportData(){let data = this.getExportData(true);// 打印出getExportData处理后的数据console.log("data--",data)// 使用 XLSX.utils.book_new() 方法创建一个新的 Excel 工作簿对象let book = XLSX.utils.book_new()// 使用 XLSX.utils.json_to_sheet 方法将 data(一个 JSON 对象数组)转换为一个 Excel 工作表。{ skipHeader: true } 选项表示在转换过程中跳过 JSON 对象的键(即表头),因为当前数据已经包含表头信息。let sheet = XLSX.utils.json_to_sheet(data, { skipHeader: true })// 将上一步创建的工作表 sheet 添加到之前创建的工作簿 book 中。XLSX.utils.book_append_sheet(book, sheet)// 使用 XLSX.write 方法将工作簿 book 转换为二进制格式的字符串。{ bookType: 'xlsx', bookSST: false, type: 'binary' } 是转换选项,指定输出的文件类型为 XLSX,并且不使用共享字符串表(Shared String Table,SST)。let wbout = XLSX.write(book, { bookType: 'xlsx', bookSST: false, type: 'binary' });// 创建一个新的 Blob 对象,其中包含通过 this.toBuffer(wbout) 方法转换后的、数据。Blob 对象用于表示一段不可变的原始数据。let blob = new Blob([this.toBuffer(wbout)], { type: 'application/octet-stream' });// 设置文件名称let exportName ="环保袋耗用量.xlsx";// 使用 FileSaver.saveAs 方法触发浏览器的文件下载功能,将 Blob 对象保存为指定的文件名 exportName(即 "环保袋耗用量.xlsx")。 FileSaver 是一个用于在客户端保存文件的库。FileSaver.saveAs(blob, exportName);
},
toBuffer(wbout) {// 创建一个新的 ArrayBuffer,其大小(以字节为单位)与 wbout 字符串的长度相同。let buf = new ArrayBuffer(wbout.length)// 创建一个新的 Uint8Array 视图,它引用 buf(即上面创建的 ArrayBuffer)。Uint8Array 是一个固定长度的原始二进制数据缓冲区,用于存储 8 位无符号整数。let view = new Uint8Array(buf)// 这是一个循环,遍历 wbout 字符串的每个字符。// wbout.charCodeAt(index) 获取字符串中第 index 个字符的 Unicode 码点。// & 0xFF 是一个按位与操作,用于确保我们只保留 Unicode 码点的低 8 位。这是必要的,因为 Unicode 码点可能是 16 位或 32 位的,但我们只想要其低 8 位。// view[index] = ... 将计算出的 8 位值存储在 view(即 ArrayBuffer)的相应位置。for (let index = 0; index !== wbout.length; ++index) view[index] = wbout.charCodeAt(index) & 0xFFreturn buf
},

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/682304.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

华为 Huawei 交换机 配置 Dot1q 终结子接口实现同设备 VLAN 间通信示例

组网需求 企业的不同部门拥有相同的业务&#xff0c;如上网、 VoIP 等业务&#xff0c;且各个部门中的用户位于不同的网段。目前存在不同的部门中相同的业务所属的VLAN 不相同&#xff0c;现需要实现不同VLAN中的用户相互通信。 如 图 7-7 所示&#xff0c;部门 1 和部门 2 中…

[Collection与数据结构] Map与Set(一):二叉搜索树与Map,Set的使用

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏:&#x1f355; Collection与数据结构 (91平均质量分)https://blog.csdn.net/2301_80050796/category_12621348.html?spm1001.2014.3001.5482 &#x1f9c0;Java …

【码银送书第十九期】《图算法:行业应用与实践》

作者&#xff1a;嬴图团队 01 前言 在当今工业领域&#xff0c;图思维方式与图数据技术的应用日益广泛&#xff0c;成为图数据探索、挖掘与应用的坚实基础。本文旨在分享嬴图团队在算法实践应用中的宝贵经验与深刻思考&#xff0c;不仅促进业界爱好者之间的交流&#xff0c;…

excel中怎么跳转到指定的单元格?

也许你会有这样的需求&#xff0c;如A1单元格中显示B100这种单元格地址&#xff0c;怎么做以点一下就跳转到B100&#xff1f; 一、设置公式 B1HYPERLINK("#"&MID(CELL("FILENAME",A1),FIND("]",CELL("FILENAME",A1))1,99)&&…

web API设计笔记

Hello , 我是小恒。今晚就讲讲我在开发维护API后的经验分享&#xff0c;当然我知识有限&#xff0c;暂时也不会写实际操作。GitHub项目仓库有一堆还在前期开发&#xff0c;我的时间很多时间投在了开源上。 推荐书籍 我认为一个好的 API 设计是面向用户的&#xff0c;充分隐藏底…

Docx文件误删除如何恢复?别再花冤枉钱了,4个高效恢复软件!

不管是工作还是学习&#xff0c;总是会与各种各样的文件打交道。文件量越多就越容易出现文件丢失、文件误删的情况。遇到这些情况&#xff0c;失去的文件还能找回来吗&#xff1f;只要掌握了一些数据恢复方法&#xff0c;是很有机会恢复回来的&#xff0c;下面我会将这些方法分…

248 基于matlab的GA-RBF神经网络预测

基于matlab的GA-RBF神经网络预测&#xff0c;遗传算法优化来训练RBF网络权值&#xff0c;RBF优化后的结果用于预测。输出真实值、RBF预测结果、GA-RBF预测结果&#xff0c;并进行对比。程序已调通&#xff0c;可直接运行。 248 RBF神经网络 GA-RBF 时间序列预测 - 小红书 (xiao…

HarmonyOS开发之ArkTS使用:用户登录页面应用

目录 目录 前言 关于HarmonyOS 环境准备 新建项目 设计用户登录页面 1. 布局设计 2. 编写ArkTS代码 运行和测试 结束语 前言 随着HarmonyOS&#xff08;鸿蒙操作系统&#xff09;的不断发展&#xff0c;越来越多的开发者开始投入到这个全新的生态系统中&#xff0c;而…

wlan二层旁挂组网实验

实验拓扑图 代码&#xff1a; SW1 <Huawei>sys Enter system view, return user view with CtrlZ. [Huawei]sysn sw1 [sw1]undo info-center enable Info: Information center is disabled. [sw1]vlan batch 10 20 30 Info: This operation may take a few seconds. …

Error: error:0308010C:digital envelope routines::unsupported 问题如何解决

Error: error:0308010C:digital envelope routines::unsupported 通常与 Node.js 的加密库中对某些加密算法的支持有关。这个错误可能是因为 Node.js 的版本与某些依赖库不兼容导致的。特别是在 Node.js 17 版本中&#xff0c;默认使用 OpenSSL 3&#xff0c;而一些旧的加密方式…

socket实现TCP UDP

1、socket通信建立流程 1.1、创建服务端流程 使用 socket 函数来创建 socket服务。 使用 bind 函数绑定端口。 使用 listen 函数监听端口。 使用 accept 函数接收客户端请求。 1.2、创建客户端流程 使用 socket 函数来创建 socket 服务。 使用 connect 函数连接到 socke…

探索智能编程新境界:我与Baidu Comate的独特体验之旅

文章目录 一、认识Baidu Comate二、VS Code安装Baidu Comate教程三、Baidu Comate功能体验功能概览具体功能1.根据注释自动生成代码2.函数注释3.行间注释4.代码解释5.生成单元测试6.代码优化7.答疑解惑 四、交互体验五、总结 一、认识Baidu Comate ✨Baidu Comate插件是一款基…