小小导出,我大前端足矣!

前言

  • 常网IT戳我呀!
  • 常网IT源码上线啦!
  • 本篇录入技术选型专栏,希望能祝君拿下Offer一臂之力,各位看官感兴趣可移步🚶。
  • 有人说面试造火箭,进去拧螺丝;其实个人觉得问的问题是项目中涉及的点 || 热门的技术栈都是很好的面试体验,不要是旁门左道冷门的知识,实际上并不会用到的。
  • 接下来想分享一些自己在项目中遇到的导出功能场景。

如果你觉得你现在做的事情很累,很难,那一定是你方法用错了。

一、问题剖析

那是一个倾盆大雨的早上,花瓣随风雨落在我的肩膀上,是五颜六色的花朵。

我轻轻抚摸着他,随后拨开第一朵花瓣,她不爱我。

拨开第二朵,她爱我。

正当我沉迷于甜蜜的幻想中,后端小白🙋喊道:这个导出你前端应该就能做的吧!

🙋🏻‍♂️那是自然,有什么功能是我大前端做不了的,必须得让你们大开眼界。

二、为什么导出要前端做?

前端导出的场景:

  1. 轻量级数据:如果要导出的表格数据相对较小,可以直接在前端生成和导出,避免服务器端的处理和通信开销。
  2. 数据已存在于前端:如果表格数据已经以 JSON 或其他形式存在于前端,可以直接利用前端技术将其导出为 Excel、CSV 或其他格式。
  3. 实时生成/计算:如果导出的表格需要根据用户输入或动态生成,可以使用前端技术基于用户操作实时生成表格,并提供导出功能。
  4. 快速响应:前端导出表格可以提供更快的响应速度,避免等待服务器端的处理和下载时间。

后端导出的场景:

  1. 大量数据:如果要导出的表格数据量很大,超过了前端处理能力或网络传输限制,那么在服务器端进行导出会更高效。
  2. 安全性和数据保护:敏感数据不适合在前端暴露,因此在服务器端进行导出可以更好地控制和保护数据的安全。
  3. 复杂的业务逻辑:如果导出涉及复杂的业务逻辑、数据处理或数据查询,使用服务器端的计算能力和数据库访问更合适。
  4. 跨平台支持:如果需要支持多个前端平台(如 Web、移动应用等),将导出功能放在服务器端可以提供一致的导出体验。

三、讲解一下在前端做的导出

xlsx、xlsx-style

如果是只做表格导出:www.npmjs.com/package/xls…

如果导出要包含样式:www.npmjs.com/package/xls…

javascript

package.json

json

"xlsx": "^0.15.5", "xlsx-style": "^0.8.13"

大概效果如下:

感觉前端导出也很容易。

哦哦,那你别高兴太早。

四、需求升级:单元格要居中和加粗。

xlsx

尝试使用xlsx-style设样式。

官方文档:github.com/rockboom/Sh…

文档说给单元格设置s为对象

4.png

 

javascript

发现设置无效。

有人说要改xlsx、xlsx-style源码:

大概的意思是:修改xlsx.extendscript.js、xlsx.full.min.js更改文件变量。

发现仍然无效。

使用binary方式保存
  1. 首先保存的时候 type要改成 binary方式
  2. 保存的时候需要使用 xlsx-style模块
 

javascript

复制代码

var writingOpt = { bookType: 'xlsx', bookSST: true, type: 'binary' // <--- 1.改这里 } /* 2. type:'array'改为'binary' 后因为下面代码会报错, 打不开excel new Blob([wbout], { type: 'application/octet-stream' } 要文本转换成数组缓存后再生成二进制对象 */ // 添加String To ArrayBuffer function s2ab(s) { var buf = new ArrayBuffer(s.length); var view = new Uint8Array(buf); for (var i = 0; i < s.length; i++) { view[i] = s.charCodeAt(i) & 0xFF; } return buf; } let blob = new Blob([s2ab(wbout)], { type: 'application/octet-stream' }) FileSaver.saveAs(blob, exportName)

可以下载了。但依然样式没起作用。

使用 xlsx-style 模块生成文件

首先安装模块

 

复制代码

npm install xlsx-style

在项目里安装报好多错误直接强制安装,不检查依赖。

 

复制代码

npm install xlsx-style -force

安装完成后 找不到cptable模块会报错
报错内容如下:

 

bash

复制代码

./node_modules/xlsx-style/dist/cpexcel.js Module not found: Error: Can't resolve './cptable' in

这个问题在vue.config.js里配置一下就可以解决。
其他框架自己找找方法,反正只要不让他报错能启动就行。

 

javascript

复制代码

module.exports = { // ...其他配置省略 configureWebpack: { // ...其他配置省略 externals:{ './cptable':'var cptable' }, },

安装完xlsx-style后改代码

 

javascript

复制代码

import XLSX2 from "xlsx-style"; // 1. 引入模块 // 2. 使用`xlsx-style` 生成。 XLSX.write => XLSX2.write var wbout = XLSX2.write(wb, writingOpt)

仍然无效。

总结xlsx

大概的意思是说:默认不支持改变样式,想要支持改变样式,需要使用它的收费版本。

本着勤俭节约的原则,很多人使用了另一个第三方库:xlsx-style[4] ,但是使用起来极其复杂,还需要改 node_modules 源码,这个库最后更新时间也定格在了 6年前。还有一些其他的第三方样式拓展库,质量参差不齐。

使用成本和后期的维护成本很高,不得不放弃。

ExcelJS

ExcelJS终于可以了

ExcelJS[5] 周下载量 450k,github star 9k,并且拥有中文文档,对国内开发者很友好。虽然文档是以README 的形式,可读性不太好,但重在内容,常用的功能基本都有覆盖。

最近更新时间是6个月内,试用了一下,集成很简单,再加之文档丰富,就选它了。

 

arduino

复制代码

npm install exceljs npm install file-saver // 下载到本地还需要另一个库:file-saver

基本操作

 

javascript

复制代码

//导入ExcelJS import ExcelJS from "exceljs"; //下载文件 download_file(buffer, fileName) { console.log("导出"); let fileURL = window.URL.createObjectURL(new Blob([buffer])); let fileLink = document.createElement("a"); fileLink.href = fileURL; fileLink.setAttribute("download", fileName); document.body.appendChild(fileLink); fileLink.click(); }

导出xlsx表格的代码

 

javascript

复制代码

//下面是导出的函数 async export() { const workbook = new ExcelJS.Workbook(); const worksheet = workbook.addWorksheet("Sheet1"); //这里是数据列表 const data = [ { id: 1, name: "艾伦", age: 20, sex: "男", achievement: 90 }, { id: 2, name: "柏然", age: 25, sex: "男", achievement: 86 }, ]; // 设置列,这里的width就是列宽 worksheet.columns = [ { header: "序号", key: "id", width: 10}, { header: "姓名", key: "name", width: 10 }, ]; // 批量插入数据 data.forEach(item => worksheet.addRow(item)); // 写入文件 const buffer = await workbook.xlsx.writeBuffer(); //下载文件 this.download_file(buffer, "填报汇总.xlsx"); }

设置行高和列宽

列宽上面已经有了,这里说明一下行高怎么设置
worksheet.getRow(2).height = 30;

合并单元格

worksheet.mergeCells("B1:C1");

自定义表格样式

 

javascript

复制代码

//设置样式表格样式,font里面设置字体大小,颜色(这里是argb要注意),加粗 //alignment 设置单元格的水平和垂直居中 const B1 = worksheet.getCell('B1') B1.font = { size: 20, color:{ argb: 'FF8B008B' }, bold: true } B1.alignment = { horizontal: 'center', vertical: 'middle' }

ExcelJS实战
 

javascript

复制代码

import ExcelJS from "exceljs"; //下载文件 download_file(buffer, fileName) { console.log("导出"); let fileURL = window.URL.createObjectURL(new Blob([buffer])); let fileLink = document.createElement("a"); fileLink.href = fileURL; fileLink.setAttribute("download", fileName); document.body.appendChild(fileLink); fileLink.click(); }, async exportClick() { const loading = this.$loading({ lock: true, text: "数据导出中,请耐心等待!", spinner: "el-icon-loading", background: "rgba(0, 0, 0, 0.7)", }); this.tableData = [ { a: 1, b:2 } ] const enterpriseVisitsColumns = [ { prop: "a", label: "银行", }, { prop: "b", label: "企业数", } ] // 表格数据:this.tableData if (!(this.tableData && this.tableData.length)) { this.$message.info("暂无数据"); loading.close(); return; } let tableName = this.tableName; // 表格名 const workbook = new ExcelJS.Workbook(); const worksheet = workbook.addWorksheet(tableName); const props = enterpriseVisitsColumns(); //这里是数据列表 const data = this.tableData; // 设置列,这里的width就是列宽 let arr = []; props.forEach((p) => { arr.push({ header: p.label, key: p.prop, width: 25, }); }); worksheet.columns = arr; // 插入一行到指定位置,现在我往表格最前面加一行,值为表名 const rowIndex = 1; // 要插入的行位置 const newRow = worksheet.insertRow(rowIndex); // 设置新行的单元格值 newRow.getCell(1).value = tableName; // 值为表名 // 批量插入数据,上面插一条,这里就是从第二行开始加 data.forEach((item) => worksheet.addRow(item)); //设置样式表格样式,font里面设置字体大小,颜色(这里是argb要注意),加粗 //alignment 设置单元格的水平和垂直居中 // const B1 = worksheet.getCell("B1"); // B1.font = { size: 20, color: { argb: "FF8B008B" }, bold: true }; // B1.alignment = { horizontal: "center", vertical: "middle" }; // 合并单元格,就是把A1开始到J1的单元格合并 worksheet.mergeCells("A1:J1"); // 批量设置所有表格数据的样式 worksheet.eachRow((row, rowNumber) => { let size = rowNumber == 1 ? 16 : rowNumber == 2 ? 12 : ""; //设置表头样式 row.eachCell((cell) => { cell.font = { size, // color:{ argb: 'FF8B008B' }, bold: true, }; cell.alignment = { horizontal: "center", vertical: "middle" }; }); //设置所有行高 row.height = 30; }); // 写入文件 const buffer = await workbook.xlsx.writeBuffer(); //下载文件 this.download_file(buffer, tableName + ".xlsx"); loading.close(); },

后记

导出功能并不是说都是前端或者后端实现,要具体情况,具体分析,我相信哪方都可以做,但谁适合做,这个才是我们需要去思考的。

就如同我们项目中,该例子后面也是前端实现的,大数据分页当然还是得后端同学来实现较好。

如果有其他更好的方法也欢迎评论区见,这里提供的只是诸多方法之一。

最后,祝君能拿下满意的offer。

我是Dignity_呱,来交个朋友呀,有朋自远方来,不亦乐乎呀!深夜末班车

👍 如果对您有帮助,您的点赞是我前进的润滑剂。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

BUU [MRCTF2020]套娃

BUU [MRCTF2020]套娃 开题&#xff0c;啥也没有。 查看网页源代码发现后端源代码&#xff1a; <?php //1st $query $_SERVER[QUERY_STRING];if( substr_count($query, _) ! 0 || substr_count($query, %5f) ! 0 ){die(Y0u are So cutE!); }if($_GET[b_u_p_t] ! 23333 &am…

面试算法-61-二叉树的右视图

题目 给定一个二叉树的 根节点 root&#xff0c;想象自己站在它的右侧&#xff0c;按照从顶部到底部的顺序&#xff0c;返回从右侧所能看到的节点值。 示例 1: 输入: [1,2,3,null,5,null,4] 输出: [1,3,4] 解 class Solution {public List<Integer> rightSideView(T…

单目测距那些事儿(上) _ 从MobileEye谈起

单目测距那些事儿(上) | 从MobileEye谈起 全面专业的自动驾驶学习资料:链接 前言 在ADAS领域&#xff0c;有个功能叫自适应巡航控制(Adaptive Cruise Control, ACC)。 ACC是一种纵向距离控制&#xff0c;具体包括发现目标车辆、判断目标车辆所在路径、测量相对本车的距离和速…

B007-springcloud alibaba 消息驱动 Rocketmq

目录 MQ简介什么是MQMQ的应用场景异步解耦流量削峰 常见的MQ产品 RocketMQ入门RocketMQ环境搭建环境准备安装RocketMQ启动RocketMQ测试RocketMQ关闭RocketMQ RocketMQ的架构及概念RocketMQ控制台安装 消息发送和接收演示发送消息接收消息 案例订单微服务发送消息用户微服务订阅…

盲盒一番赏小程序开发:神秘惊喜,等你来揭晓

在当下潮流文化中&#xff0c;盲盒以其独特的魅力&#xff0c;正逐渐成为一种流行的娱乐方式。为了满足广大盲盒爱好者的需求&#xff0c;我们决定开发一款盲盒一番赏小程序&#xff0c;为用户带来更加便捷、丰富的盲盒体验。 一、小程序简介 盲盒一番赏小程序是一个集盲盒购…

应用测评要求解读-三级

身份鉴别&#xff1a; a)应对登录的用户进行身份标识和鉴别&#xff0c;身份标识具有唯一性&#xff0c;身份鉴别信息具有复杂度要求并定期更换&#xff1b; 1. 在未登录状态下尝试直接访问任意操作页面或功能&#xff0c;查看是否具有登陆界面。 2&#xff0e;询问或者测试…

【算法刷题】Day32

文章目录 1. 单词拆分题干&#xff1a;算法原理&#xff1a;1. 状态表示&#xff1a;2. 状态转移方程3. 初始化4. 填表顺序5. 返回值 代码&#xff1a; 2. 环绕字符串中唯一的子字符串题干&#xff1a;算法原理&#xff1a;1. 状态表示&#xff1a;2. 状态转移方程3. 初始化4. …

关于Ansible的模块 ①

转载说明&#xff1a;如果您喜欢这篇文章并打算转载它&#xff0c;请私信作者取得授权。感谢您喜爱本文&#xff0c;请文明转载&#xff0c;谢谢。 什么是Ansible模块 在Linux中&#xff0c;bash无论是在命令行上执行&#xff0c;还是在bash脚本中&#xff0c;都需要调用cd、l…

MySQL最实用面试题(2024-3-14持续更新中)

MySQL篇面试题 一、介绍 ​ 这是由小龙同学自己总结领悟的mysql面试题的解析&#xff0c;也是面试宝典 二、题目 1.数据库三大范式&#xff1a; –作用&#xff1a; ​ 使表结构清晰&#xff0c;减少数据冗余&#xff08;简单讲就是重复&#xff09;&#xff0c;提高查询…

Stable Diffusion + Segment Anything试用

安装 从continue-revolution/sd-webui-segment-anything安装插件分割模型下载后放到这个位置&#xff1a;${sd-webui}/extension/sd-webui-segment-anything/models/sam下&#xff0c;可以下载3个不同大小的模型&#xff0c;从大到小如下&#xff1a;vit_h is 2.56GB, vit_l i…

test测试类-变量学习

test测试类 作用&#xff1a;标记到类上成为测试类&#xff0c;标记到方法上成为测试方法 变量&#xff1a;测试类的变量&#xff0c;在测试类括号中应用 1、invocationCount变量 意思是这个方法应该被调用的次数。 在测试框架中&#xff0c;特别是当使用参数化测试或数据驱动…

游戏陪玩系统约玩系统交友系统功能介绍

游戏约玩系统是一个集动态社交、语聊交友、线上约玩、线下活动以及购物商城等功能于一体的综合性平台。以下是该系统的功能介绍&#xff1a; 一、首页 热门大神&#xff1a;展示平台上最受欢迎的玩家&#xff0c;方便用户快速找到高水平的游戏伙伴。附近大神&#xff1a;基于…

openGauss学习笔记-246 openGauss性能调优-SQL调优-经验总结:SQL语句改写规则

文章目录 openGauss学习笔记-246 openGauss性能调优-SQL调优-经验总结&#xff1a;SQL语句改写规则246.1 使用union all代替union246.2 join列增加非空过滤条件246.3 not in转not exists246.4 选择hashagg246.5 尝试将函数替换为case语句246.6 避免对索引使用函数或表达式运算2…

Android 系统如何添加开机自启动 Shell 脚本

添加开机自启动 Shell 脚本 很多时候&#xff0c;我们想在系统启动的时候干一些“私活”&#xff0c;这个时候&#xff0c;我们就可以添加开机自启动的脚本来完成。下面我们介绍一个简单的示例&#xff1a; 在 device/Jelly/Rice14 目录下添加如下的文件与文件夹&#xff1a;…

RPC 和 序列化

RPC 1 RPC调用流程 1.1 clerk客户端调用远程服务 Clerk::PutAppend() raftServerRpcUtil::PutAppend() raftServerRpcUtil是client与kvserver通信的入口&#xff0c; 包含kvserver功能的一对一映射&#xff1a;Get/PutAppend&#xff0c;通过stub对象——raftKVRpcProctoc:…

HarmonyOS NEXT应用开发—图片压缩方案

介绍 图片压缩在应用开发中是一个非常常见的需求&#xff0c;特别是在处理用户上传图片时&#xff0c;需要上传指定大小以内的图片。目前图片压缩支持jpeg、webp、png格式。本例中以jpeg图片为例介绍如何通过packing和scale实现图片压缩到目标大小以内。 效果图预览 使用说明…

Catmull-Rom P5 ThreeJs与前端

文章目录 问题Echarts 3D如何让曲线变得平滑&#xff1f;Echarts 2D图中平滑效果是如何实现的&#xff1f;如何在一个Echarts 3D图中画一个圆圈&#xff1f;如何在Echarts 3D图中画一个立方体&#xff1f; Catmull-Rom插值算法先来回答第二个问题回到第一个问题在Echarts 3D图中…

运维安全管理与审计系统(堡垒机)

一、什么是运维安全管理与审计系统 运维安全管理与审计系统&#xff08;俗称 “堡垒机”&#xff09;&#xff1a;是采用新一代智能运维技术框架&#xff0c;基于认证、授权、访问、审计的管理流程设计理念&#xff0c;实现对企事业IT中心的网络设备、数据库、安全设备、主机系…

Zustand极简的状态管理工具

介绍 一个小型、快速且可扩展的 Bearbones 状态管理解决方案。 Zustand 有一个基于 hooks 的舒适 API。它不是样板文件或固执己见&#xff0c;但有足够的惯例来明确和类似通量。 zustand官网 zustand使用方法及调试工具的安装使用 安装包 npm install zustand2.创建store仓…

【Unity投屏总结】投屏方案总结

【背景】 想方便自己在VR中工作&#xff0c;打算做一个能够挂多个屏幕的远程控制VR桌面。研究下来发现细分场景有很多&#xff0c;有点鱼和熊掌不可兼得的意味&#xff0c;细分如下。 【投屏场景与解决方案】 希望多人能够同时观看我的屏幕&#xff0c;也就是一屏投多屏&…