范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

前端导出Excel,让后端刮目相看

  前言
  这几天在开发中遇到一个事情,做一个导出的功能,但是后台是新来的菜鸟,等了三天没反应,接口做不出来,我内心一万个…,于是乎我就打算前端做导出了,网上复制了一些代码就出来了。导入依赖// npm npm install -S file-saver xlsx npm install -D script-loader 复制代码导入Bolb.js与Export2Excel.js
  首先拷贝以下两个文件代码: Export2Excel.js/* eslint-disable */ require("script-loader!file-saver"); require("script-loader!vendor/Blob"); require("script-loader!xlsx/dist/xlsx.core.min"); function generateArray(table) {     var out = [];     var rows = table.querySelectorAll("tr");     var ranges = [];     for (var R = 0; R < rows.length; ++R) {         var outRow = [];         var row = rows[R];         var columns = row.querySelectorAll("td");         for (var C = 0; C < columns.length; ++C) {             var cell = columns[C];             var colspan = cell.getAttribute("colspan");             var rowspan = cell.getAttribute("rowspan");             var cellValue = cell.innerText;             if (cellValue !== "" && cellValue == +cellValue) cellValue = +cellValue;             //Skip ranges             ranges.forEach(function (range) {                 if (R >= range.s.r && R <= range.e.r && outRow.length >= range.s.c && outRow.length <= range.e.c) {                     for (var i = 0; i <= range.e.c - range.s.c; ++i) outRow.push(null);                 }             });             //Handle Row Span             if (rowspan || colspan) {                 rowspan = rowspan || 1;                 colspan = colspan || 1;                 ranges.push({s: {r: R, c: outRow.length}, e: {r: R + rowspan - 1, c: outRow.length + colspan - 1}});             }             ;             //Handle Value             outRow.push(cellValue !== "" ? cellValue : null);             //Handle Colspan             if (colspan) for (var k = 0; k < colspan - 1; ++k) outRow.push(null);         }         out.push(outRow);     }     return [out, ranges]; }; function datenum(v, date1904) {     if (date1904) v += 1462;     var epoch = Date.parse(v);     return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000); } function sheet_from_array_of_arrays(data, opts) {     var ws = {};     var range = {s: {c: 10000000, r: 10000000}, e: {c: 0, r: 0}};     for (var R = 0; R != data.length; ++R) {         for (var C = 0; C != data[R].length; ++C) {             if (range.s.r > R) range.s.r = R;             if (range.s.c > C) range.s.c = C;             if (range.e.r < R) range.e.r = R;             if (range.e.c < C) range.e.c = C;             var cell = {v: data[R][C]};             if (cell.v == null) continue;             var cell_ref = XLSX.utils.encode_cell({c: C, r: R});             if (typeof cell.v === "number") cell.t = "n";             else if (typeof cell.v === "boolean") cell.t = "b";             else if (cell.v instanceof Date) {                 cell.t = "n";                 cell.z = XLSX.SSF._table[14];                 cell.v = datenum(cell.v);             }             else cell.t = "s";             ws[cell_ref] = cell;         }     }     if (range.s.c < 10000000) ws["!ref"] = XLSX.utils.encode_range(range);     return ws; } function Workbook() {     if (!(this instanceof Workbook)) return new Workbook();     this.SheetNames = [];     this.Sheets = {}; } 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; } export function export_table_to_excel(id) {     var theTable = document.getElementById(id);     console.log("a")     var oo = generateArray(theTable);     var ranges = oo[1];     /* original data */     var data = oo[0];     var ws_name = "SheetJS";     console.log(data);     var wb = new Workbook(), ws = sheet_from_array_of_arrays(data);     /* add ranges to worksheet */     // ws["!cols"] = ["apple", "banan"];     ws["!merges"] = ranges;     /* add worksheet to workbook */     wb.SheetNames.push(ws_name);     wb.Sheets[ws_name] = ws;     var wbout = XLSX.write(wb, {bookType: "xlsx", bookSST: false, type: "binary"});     saveAs(new Blob([s2ab(wbout)], {type: "application/octet-stream"}), "test.xlsx") } function formatJson(jsonData) {     console.log(jsonData) } export function export_json_to_excel(th, jsonData, defaultTitle) {     /* original data */     var data = jsonData;     data.unshift(th);     var ws_name = "SheetJS";     var wb = new Workbook(), ws = sheet_from_array_of_arrays(data);     /* add worksheet to workbook */     wb.SheetNames.push(ws_name);     wb.Sheets[ws_name] = ws;     var wbout = XLSX.write(wb, {bookType: "xlsx", bookSST: false, type: "binary"});     var title = defaultTitle || "列表"     saveAs(new Blob([s2ab(wbout)], {type: "application/octet-stream"}), title + ".xlsx") } 复制代码
  Blob.js (function (view) {     "use strict";     view.URL = view.URL || view.webkitURL;     if (view.Blob && view.URL) {         try {             new Blob;             return;         } catch (e) {}     }     // Internally we use a BlobBuilder implementation to base Blob off of     // in order to support older browsers that only have BlobBuilder     var BlobBuilder = view.BlobBuilder || view.WebKitBlobBuilder || view.MozBlobBuilder || (function(view) {             var                 get_class = function(object) {                     return Object.prototype.toString.call(object).match(/^[objects(.*)]$/)[1];                 }                 , FakeBlobBuilder = function BlobBuilder() {                     this.data = [];                 }                 , FakeBlob = function Blob(data, type, encoding) {                     this.data = data;                     this.size = data.length;                     this.type = type;                     this.encoding = encoding;                 }                 , FBB_proto = FakeBlobBuilder.prototype                 , FB_proto = FakeBlob.prototype                 , FileReaderSync = view.FileReaderSync                 , FileException = function(type) {                     this.code = this[this.name = type];                 }                 , file_ex_codes = (                     "NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR "                     + "NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR"                 ).split(" ")                 , file_ex_code = file_ex_codes.length                 , real_URL = view.URL || view.webkitURL || view                 , real_create_object_URL = real_URL.createObjectURL                 , real_revoke_object_URL = real_URL.revokeObjectURL                 , URL = real_URL                 , btoa = view.btoa                 , atob = view.atob                 , ArrayBuffer = view.ArrayBuffer                 , Uint8Array = view.Uint8Array                 ;             FakeBlob.fake = FB_proto.fake = true;             while (file_ex_code--) {                 FileException.prototype[file_ex_codes[file_ex_code]] = file_ex_code + 1;             }             if (!real_URL.createObjectURL) {                 URL = view.URL = {};             }             URL.createObjectURL = function(blob) {                 var                     type = blob.type                     , data_URI_header                     ;                 if (type === null) {                     type = "application/octet-stream";                 }                 if (blob instanceof FakeBlob) {                     data_URI_header = "data:" + type;                     if (blob.encoding === "base64") {                         return data_URI_header + ";base64," + blob.data;                     } else if (blob.encoding === "URI") {                         return data_URI_header + "," + decodeURIComponent(blob.data);                     } if (btoa) {                         return data_URI_header + ";base64," + btoa(blob.data);                     } else {                         return data_URI_header + "," + encodeURIComponent(blob.data);                     }                 } else if (real_create_object_URL) {                     return real_create_object_URL.call(real_URL, blob);                 }             };             URL.revokeObjectURL = function(object_URL) {                 if (object_URL.substring(0, 5) !== "data:" && real_revoke_object_URL) {                     real_revoke_object_URL.call(real_URL, object_URL);                 }             };             FBB_proto.append = function(data/*, endings*/) {                 var bb = this.data;                 // decode data to a binary string                 if (Uint8Array && (data instanceof ArrayBuffer || data instanceof Uint8Array)) {                     var                         str = ""                         , buf = new Uint8Array(data)                         , i = 0                         , buf_len = buf.length                         ;                     for (; i < buf_len; i++) {                         str += String.fromCharCode(buf[i]);                     }                     bb.push(str);                 } else if (get_class(data) === "Blob" || get_class(data) === "File") {                     if (FileReaderSync) {                         var fr = new FileReaderSync;                         bb.push(fr.readAsBinaryString(data));                     } else {                         // async FileReader won"t work as BlobBuilder is sync                         throw new FileException("NOT_READABLE_ERR");                     }                 } else if (data instanceof FakeBlob) {                     if (data.encoding === "base64" && atob) {                         bb.push(atob(data.data));                     } else if (data.encoding === "URI") {                         bb.push(decodeURIComponent(data.data));                     } else if (data.encoding === "raw") {                         bb.push(data.data);                     }                 } else {                     if (typeof data !== "string") {                         data += ""; // convert unsupported types to strings                     }                     // decode UTF-16 to binary string                     bb.push(unescape(encodeURIComponent(data)));                 }             };             FBB_proto.getBlob = function(type) {                 if (!arguments.length) {                     type = null;                 }                 return new FakeBlob(this.data.join(""), type, "raw");             };             FBB_proto.toString = function() {                 return "[object BlobBuilder]";             };             FB_proto.slice = function(start, end, type) {                 var args = arguments.length;                 if (args < 3) {                     type = null;                 }                 return new FakeBlob(                     this.data.slice(start, args > 1 ? end : this.data.length)                     , type                     , this.encoding                 );             };             FB_proto.toString = function() {                 return "[object Blob]";             };             FB_proto.close = function() {                 this.size = this.data.length = 0;             };             return FakeBlobBuilder;         }(view));     view.Blob = function Blob(blobParts, options) {         var type = options ? (options.type || "") : "";         var builder = new BlobBuilder();         if (blobParts) {             for (var i = 0, len = blobParts.length; i < len; i++) {                 builder.append(blobParts[i]);             }         }         return builder.getBlob(type);     }; }(typeof self !== "undefined" && self || typeof window !== "undefined" && window || this.content || this)); 复制代码
  因为我们在Export2Excel.js中设置的Blob路径为vendor,所以我们要在src下建立相关文件夹并放入这两个js。
  设置导出表格数据
  假设我们需要导出一个这样的表格
  数据// data dataList: [     { name: "张明", loginTime: 16, id: 1, department: "生产部", sex: "男" },     { name: "小金", loginTime: 11, id: 2, department: "生产部", sex: "女" },     { name: "小凌", loginTime: 21, id: 3, department: "生产部", sex: "男" },     { name: "盖伦", loginTime: 5, id: 4, department: "测试部", sex: "男" } ] 复制代码
  html
ID 名称 登陆次数 部门
{{ item.id }} {{ item.name }} {{ item.loginTime }} {{ item.department }}
复制代码   methods // 导出excel exportExcel() { // 引入文件 const { export_json_to_excel } = require("vendor/Export2Excel.js"); // 表头 const tHeader = ["ID", "名称", "登陆次数", "部门"]; // table表格中对应的属性名 const filterVal = ["id", "name", "loginTime", "department"]; // 表格绑定数据转json const data = this.formatJson(filterVal, this.dataList); export_json_to_excel( tHeader, data, "部门登陆信息" + new Date().toLocaleDateString() ); // 对应下载文件的名字 }, // 导出列表格式化数据的方法 formatJson(filterVal, jsonData) { return jsonData.map(v => filterVal.map(j => v[j])); } 复制代码   展示效果   到此,前端导出功能实现。这种方式的优势在于:1.不用请求后端获取文件。2.所见即所得,前端可有灵活地把控输出的数据,不用因为导出的数据有差错而拉着后端一起联调。多sheet导出   我们可能有时候会遇到对Excel多sheet的操作,比如部门的多季度绩效分多sheet导出。   我们需要在Export2Excel.js中添加一个方法:/** * 多sheet导出 * @param {Array} th 表头 * @param {Array} jsonDatas 数据集 * @param {String} defaultTitle 导出的excel名称 * @param {Array} sheetNames sheet名称集 */ export function export_season_to_excel(th, jsonDatas, defaultTitle, sheetNames) { var wb = new Workbook() jsonDatas.forEach((item, index) => { var data = item; data.unshift(th); var ws_name = sheetNames[index]; var ws = sheet_from_array_of_arrays(data); /* add worksheet to workbook */ wb.SheetNames.push(ws_name); wb.Sheets[ws_name] = ws; }) var wbout = XLSX.write(wb, { bookType: "xlsx", bookSST: false, type: "binary" }); var title = defaultTitle || "列表" saveAs(new Blob([s2ab(wbout)], { type: "application/octet-stream" }), title + ".xlsx") } 复制代码   页面中的data内容:// data 季度绩效数据 seasonDatas: [ [ { name: "张明", score: 72 }, { name: "小金", score: 21 }, { name: "小凌", score: 16 }, { name: "盖伦", score: 84 } ], [ { name: "张明", score: 32 }, { name: "小金", score: 54 }, { name: "小凌", score: 45 }, { name: "盖伦", score: 26 } ], [ { name: "张明", score: 67 }, { name: "小金", score: 87 }, { name: "小凌", score: 45 }, { name: "盖伦", score: 78 } ], [ { name: "张明", score: 54 }, { name: "小金", score: 34 }, { name: "小凌", score: 26 }, { name: "盖伦", score: 34 } ] ] 复制代码   html 复制代码   执行方法 // methods 导出绩效信息excel exportSeason() { // 引入文件 const { export_season_to_excel } = require("vendor/Export2Excel.js"); // 表头 const tHeader = ["名称", "绩效分"]; // table表格中对应的属性名 const filterVal = ["name", "score"]; let datas = []; let sheets = []; this.seasonDatas.forEach((item, index) => { // 表格绑定数据转json datas.push(this.formatJson(filterVal, item)); sheets.push(`第${index + 1}季度绩效`); }); export_season_to_excel( tHeader, datas, "部门季度绩效" + new Date().toLocaleDateString(), sheets ); // 对应下载文件的名字 }, 复制代码   展示效果:   至此,多Sheet导出我们也完成了。项目地址   项目地址:https://github.com/FireSmallPanda/vuexDemo.git   存疑解析大数据导出和自定义表头名称   在文章发出后大家对大数据导出和怎么自定义表头存在疑惑,我这边设置了一个可以自定义导出规模的例子。   html部分

复制代码   js部分// data rows: 100, // 行 cols: 100 // 列 // methods // 导出自定义数据 outPutBigData() { // 引入文件 const { export_json_to_excel } = require("vendor/Export2Excel.js"); // 表头 let tHeader = []; // table表格中对应的属性名 let filterVal = []; // 需要导出的内容 let pushData = []; // 自定义生成列 for (let i = 0; i < this.cols * 1; i++) { tHeader.push(`第${i + 1}列数据`); filterVal.push(i); } // 生成自定义数据 for (let j = 0; j < this.rows * 1; j++) { let pushObj = {}; for (let i = 0; i < this.cols * 1; i++) { // 这边为展示数据不一致性设置为随机数 pushObj[i] = Math.random(); } // 插入一条数据 pushData.push(pushObj); } // ---至此模拟后端请求数据结束--- // 表格绑定数据转json const data = this.formatJson(filterVal, pushData); export_json_to_excel( tHeader, data, "自定义导出数据" + new Date().toLocaleDateString() ); // 对应下载文件的名字 }, 复制代码   演示效果:   为方便大家直观的看到,我们这次导出10000行10列的随机数据.可以看到,其中的列名称我也是自动生成的。   作者:有趣的老凌   链接:https://juejin.cn/post/7030291455243452429   来源:稀土掘金   著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


微信安卓版8。0。18内测更新增加个人信息收集清单微信安卓版8。0。18内测更新,增加个人信息收集清单此前腾讯微信团队发布了微信安卓8。0。18内测版,在微信8。0。18更新中,隐私权限进一步明确,除了之前的个人信息与权限查询之外数科日报丨腾讯拟收购手机厂商黑鲨俞敏洪回应新东方辞退员工01丨腾讯拟收购小米系手机厂商黑鲨腾讯拟收购游戏手机公司黑鲨科技,收购后,黑鲨整体将并入任宇昕主导的腾讯集团平台与内容事业群(PCG)。一旦交易完成,这家以游戏手机为主的硬件厂商也围观!2021最好的4款国产手机颜值高,性能强,玩游戏不卡顿点击关注,每天精彩不断!导读围观!2021最好的4款国产手机颜值高,性能强,玩游戏不卡顿!众所周知,现在智能手机厂家发布新手机的频率还是比较高的,几乎每隔一段时间市场上都会有新款的年底送父母什么手机?首选这3款,配置强悍价格还不高马上临近过年了,在自己各种消费的同时有没有想过给爸妈买一部手机呢,毕竟现在父母也喜欢刷抖音看视频,并且还关注微信步数,出去玩也会拍照什么的,再用手里的老年机确实不太合适了,正好小编折叠屏手机爆火,三星占9成以上市场,华为小米内卷取暖随着国内手机厂商新玩家入局,折叠屏手机引发空前关注,似乎成为行业的下一个兵家必争之地。根据最新报告显示,三星在折叠屏领域拥有垄断地位,其占比超过90以上,而国产手机市场份额则可以忽华为5G手机上架,40MP三摄HMS系统128GB,价格良心,你买单吗?华为手机赢得了全球消费者的支持和认可,从工艺和硬件软件技术层面来看,华为真的是做到了国内一流水准,特别是高端市场,P系列和Mate系列打造国产最高定位,华为手机的销量也达到了巅峰,2021年最佳三星Galaxy手机排行榜超骇性能完美屏,你喜欢吗?哈喽,您好!我是原呵呵,点点关注吧,更多精彩内容等着您在智能手机领域,在全球品牌知名度方面,只有三星才能真正与苹果竞争。三星生产的产品种类繁多,几乎可以满足所有人的需求。这是我根据这才是真正的科技重器,中国5大黑科技曝光,个个令老外羡慕不已图为中国磁悬浮高铁在拥有了强大的综合国力之后,中国在各个领域内都获得了巨大突破,研究出了大量让西方也羡慕的技术,前段时间中国近年来研发出的五大黑科技装备曝光,个个令老外都羡慕不已,爆料配置小米12发布会即将召开小米12发布会于2021。12。28日召开,本文搜集了目前所有的爆料配置如下后置摄像头(12pro)后置摄像头电池电池新突破充电器充电器突破依旧挂着全球首发噱头的高通骁龙8Gen1小米高管如果小米12不做小屏,安卓阵营没有机型能对标iPhone13小米12系列马上就要发布了,目前可以确认的是小米12系列会两款不同定位的高端机型,分别是小米12和小米12Pro,其中小米12Pro是当前常见的手机尺寸,而小米12则是主打小屏市场三星S22Ultra提前上手,各种细节全部泄露看似大家目前关注的目光都在国产骁龙8Gen1机型之上,其它三星那边一点都没有闲着。正在抓紧准备三星GalaxyS22系列,其中最受人关注的S22Ultra版现在已经有人放出了真机上
矿视界译文EIP1559上线后的效果如何?自EIP1559激活以来,以太坊网络已经销毁了超过20,000ETH,这占同期新代币发行量的36,以太坊的平均交易手续费略有增加,从升级前的0。003ETH上涨至0。005ETH。经典在延续,雷蛇黑寡妇蜘蛛精英版简评作为雷蛇键盘热门黑寡妇蜘蛛系列最新版本,也是黑寡妇蜘蛛的新旗舰,雷蛇自然对这把键盘寄予了很高的期望。旗舰这两个字所能代表的就是一个品牌的最高水准,品牌也会不遗余力的拿出看家的本事,手感再次优化,经典双模108机械GANSSGM108D到站秀34期GANSS的GM108D的立足之本是性价比有线蓝牙双模PBT热升华和双口USBHUB。通过整体配置,结合樱桃轴体打造差异化,最近针对大键做了一次手感优化,提升顺畅度降低触底噪音,整专业FPS游戏键盘,金士顿HyperX阿洛伊键盘解读作为金士顿进军机械键盘领域的首款键盘,金士顿HyperX阿洛伊这款键盘可谓是肩负重任。在其它硬件厂商已经在机械键盘领域站稳了脚跟,取得了不错的成绩,金士顿的这款键盘才姗姗来迟。Hy摇杆式另类侧键,小鸡GM200独特的游戏鼠标外设是一个科技技术门槛不高的领域,找对自己的定位角度,进入并不难。所以我们能够看到如今各大硬件板卡厂商纷纷推出自己的外设产品,其中也不乏精品。对于消费者来说提供了更多的选择性,其中它号称文武双全,雷蛇刺鳞树蝰鼠标这款刺鳞树蝰是雷蛇的第二款蓝牙鼠标(第一款为八岐大蛇),虽然不是最新产品,但是融合三模的它也是雷蛇无线产品与时俱进的表现,PMW3339引擎,2。4G蓝牙双无线,至少在35年内可以全金属机身的机械键盘能做到多么简洁,IQUNIXF60sIQUNIX一直坚持的苹果风式简约设计和习惯用金属作为产品主要材质而被广大用户调侃为铝厂,与刚厂赛睿灯厂雷蛇画厂QPAD这些外设品牌称呼类似,说明IQUNIX与外设是有所特色,并形矿视界译文如何挑选Chia矿池自上个月新Chia矿池协议上线后,市面上陆续出现了许多Chia矿池。选择一个安全可靠的矿池对于挖矿来说是至关重要的,因此矿工在加入一个矿池之前需要多方比较,仔细做些功课,不能仅仅关矿视界译文除了存储,Filecoin上还有哪些商机?云服务界的AirbnbFilecoin和Airbnb(爱彼迎,全球最大的旅行房屋租赁社区)其实有不少共同点Airbnb屋主为旅客提供自己的房屋,Filecoin存储矿工为用户提供自矿视界译文IPFS助推NFT浪潮我们在2021年见证了NFT的大爆发,NFT的核心价值主张是持久性(Permanence)和不可变性(Immutability)。然而,由于设计缺陷,市面上许多用于出售的NFT都做高阶自动驾驶的量产车型摩卡预售17。984月19日,WEY品牌全球代言人WEY摩卡首席智能体验官姚安娜,空降上海车展智动WEY来摩卡专属日,携手全球首款智能汽车人WEY摩卡,为现场粉丝呈现了车展史上自动驾驶走秀,书写了其