合肥专业建站,源码WordPress,什么叫网站根目录,宁波网站建设的过程背景#xff1a;最近vue项目遇到一个需求#xff0c;就是需要将多个表格分成不同sheet页并导出#xff0c;之前的工具类只能导出一个sheet页#xff0c;所以在原有的基础上#xff0c;调整一下#xff0c;让它支持多sheet导出。
vue blob文件流#xff0c;这个肯定要的…背景最近vue项目遇到一个需求就是需要将多个表格分成不同sheet页并导出之前的工具类只能导出一个sheet页所以在原有的基础上调整一下让它支持多sheet导出。
vue blob文件流这个肯定要的这个百度一下都有下面贴出来 (function (view) {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 BlobBuildervar BlobBuilder view.BlobBuilder || view.WebKitBlobBuilder || view.MozBlobBuilder || (function(view) {varget_class function(object) {return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[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) {vartype 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 stringif (Uint8Array (data instanceof ArrayBuffer || data instanceof Uint8Array)) {varstr , 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 wont work as BlobBuilder is syncthrow 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 stringbb.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));Ex2ExcelUtils.js导出工具类
require(script-loader!file-saver);
require(./Blob);
require(script-loader!xlsx/dist/xlsx.core.min);/*** 支持多sheet* param sheetNames* param ths 表头* param jsonDatas 数据* param defaultTitle*/
export function export_data_to_excel(sheetNames, ths, jsonDatas, defaultTitle) {var wb new Workbook()for(let index in sheetNames){let th ths[index]var data deepCopy(jsonDatas[index]);data.unshift(th);var ws_name sheetNames[index];var ws sheet_from_array_of_arrays(data);//表格宽度自适应/*设置worksheet每列的最大宽度*/const colWidth data.map(row row.map(val {/*先判断是否为null/undefined*/if (val null || val undefined || val ) {return {wch: 10};} else if (val.toString().charCodeAt(0) 255) {/*再判断是否为中文*/return {wch: val.toString().length * 2};} else {return {wch: val.toString().length * 1.4};}}));/*以主表第二行为初始值因为我的第一行是表格标题会比较长所以以主表第二行为初始值*/let result colWidth[1];for (let i 1; i colWidth.length; i) {for (let j 0; j colWidth[i].length; j) {if (result[j][wch] colWidth[i][j][wch]) {result[j][wch] colWidth[i][j][wch];}}}ws[!cols] result;//表格宽度自适应-结束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}), defaultTitle .xlsx)
}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;
}上述两个文件放在同一个目录下以下是调用示例
// 文件名
const excelName 多sheet页数据导出
// 声名每个sheet页的名称
let sheetNames [sheet1, sheet2, sheet3]
// 每个sheet页的表头
let ths [[], [], []]
// 每个sheet页的数据内容
let jsonDatas [[], [], []]// sheet1
ths[0] [表头A1, 表头A2, 表头A3, 表头A4]
jsonDatas[0] [[值A1, 值A2, 值A3, 值A4],[值B1, 值B2, 值B3, 值B4]]
// sheet2
ths[1] [表头A11, 表头A21, 表头A31, 表头A41]
jsonDatas[1] [[值A11, 值A21, 值A31, 值A41],[值B11, 值B21, 值B31, 值B41]]
// sheet3
ths[2] [表头A12, 表头A22, 表头A32, 表头A42]
jsonDatas[2] [[值A12, 值A22, 值A32, 值A42],[值B12, 值B22, 值B32, 值B42]]const { export_data_to_excel} require(./Ex2ExcelUtils)
export_data_to_excel(sheetNames, ths, jsonDatas, excelName)最后前端或后端导出文件可以看自己需求。数据量比较少的时候或页面展示的是所有数据的时候使用前端js直接导出文件比较方便因为不用重查接口减少了交互。若数据量比较大或页面展示的是分页时推荐走后端接口导出文件因为没法拿到完整的数据而且大数据量从接口返回到前端对前端负担也不友好。