vue导出Excel文件

1、需要安装file-saver和script-loader、xlsx

  

npm install file-saver / yarn add file-saver

npm install script-loader / yarn add script-loader

npm install xlsx / yarn add xlsx

  

2、新建js文件(Blob.js和Export2Excel.js)

Blob.js

/* eslint-disable */
/* Blob.js*/

/*global self, unescape */

/*! @source http://purl.eligrey.com/github/Blob.js/blob/master/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(/^\[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

			, origin = /^[\w-]+:\/*\[?[\w\.:-]+\]?(?::[0-9]+)?/
		;
		FakeBlob.fake = FB_proto.fake = true;
		while (file_ex_code--) {
			FileException.prototype[file_ex_codes[file_ex_code]] = file_ex_code + 1;
		}
		// Polyfill URL
		if (!real_URL.createObjectURL) {
			URL = view.URL = function (uri) {
				var
					uri_info = document.createElementNS("http://www.w3.org/1999/xhtml", "a")
					, uri_origin
				;
				uri_info.href = uri;
				if (!("origin" in uri_info)) {
					if (uri_info.protocol.toLowerCase() === "data:") {
						uri_info.origin = null;
					} else {
						uri_origin = uri.match(origin);
						uri_info.origin = uri_origin && uri_origin[1];
					}
				}
				return uri_info;
			};
		}
		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) {
			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 = 0;
			delete this.data;
		};
		return FakeBlobBuilder;
	}(view));

	view.Blob = function (blobParts, options) {
		var type = options ? (options.type || "") : "";
		var builder = new BlobBuilder();
		if (blobParts) {
			for (var i = 0, len = blobParts.length; i < len; i++) {
				if (Uint8Array && blobParts[i] instanceof Uint8Array) {
					builder.append(blobParts[i].buffer);
				}
				else {
					builder.append(blobParts[i]);
				}
			}
		}
		var blob = builder.getBlob(type);
		if (!blob.slice && blob.webkitSlice) {
			blob.slice = blob.webkitSlice;
		}
		return blob;
	};

	var getPrototypeOf = Object.getPrototypeOf || function (object) {
		return object.__proto__;
	};
	view.Blob.prototype = getPrototypeOf(new view.Blob());
}(
	typeof self !== "undefined" && self
	|| typeof window !== "undefined" && window
	|| this
));

Export2Excel.js

 

/*导出单个sheet*/
/* eslint-disable */
require('script-loader!file-saver');
// require('script-loader!src/vendor/Blob');
require('./Blob.js');
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);
	var oo = generateArray(theTable);
	var ranges = oo[1];

	/* original data */
	var data = oo[0];
	var ws_name = "SheetJS";

	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")
}

3、在需要的地方中应用

methods: {
    exportFile () {
       const _vm = this;
       let excelList = [
         {id: 1, name: 'xiaoming', age: 10},
         {id: 2, name: 'xiaohong', age: 15},
       ]
       //excel数据导出
              require.ensure([], () => {
                const {
                  export_json_to_excel
                } = require('./js/Export2Excel');
               // 表头
                const tHeader = ['id', '名字', '年龄'];
               // 字段对应
                const filterVal = ['id', 'name', 'age'];
                const data = _vm.formatJson(filterVal, excelList );
                export_json_to_excel(tHeader, data, '人员列表');
              })
      },
     // 导出表格的json
     formatJson(filterVal, jsonData) {
        return jsonData.map(v => filterVal.map(j => v[j]))
     }
}    

4、导出多个sheet表

新建一个Export3Excel.js

/*导出多个sheet*/
/* eslint-disable */
require("script-loader!file-saver")
require('./Blob.js');
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 ( let 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)
	var oo = generateArray(theTable)
	var ranges = oo[1]

	/* original data */
	var data = oo[0]
	var ws_name = "SheetJS"

	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"
	)
}

//主要修改此函数内的方法

export function export_json_to_excel({
	                                     multiHeader = [],
	                                     header,
	                                     data,
	                                     sheetname,
	                                     filename,
	                                     merges = [],
	                                     autoWidth = true,
	                                     bookType = "xlsx"
                                     } = {}) {
	/* original data */
	filename = filename || "excel-list"
	data = [...data]

	for (var i = 0; i < header.length; i++) {
		data[i].unshift(header[i])
	}

	// data.unshift(header)

	for (let i = multiHeader.length - 1; i > -1; i--) {
		data.unshift(multiHeader[i])
	}

	var ws_name = sheetname
	var wb = new Workbook(),
		ws = []
	for (var j = 0; j < header.length; j++) {
		ws.push(sheet_from_array_of_arrays(data[j]))
	}

	if (merges.length > 0) {
		if (!ws["!merges"]) ws["!merges"] = []
		merges.forEach(item => {
			ws["!merges"].push(XLSX.utils.decode_range(item))
		})
	}
	if (autoWidth) {
		/*设置worksheet每列的最大宽度*/
		var colWidth = []
		for (var k = 0; k < header.length; k++) {
			colWidth.push(
				data[k].map(row =>
					row.map(val => {
						/*先判断是否为null/undefined*/
						if (val == null) {
							return {
								wch: 10
							}
						} else if (val.toString().charCodeAt(0) > 255) {
							/*再判断是否为中文*/
							return {
								wch: val.toString().length * 2
							}
						} else {
							return {
								wch: val.toString().length
							}
						}
					})
				)
			)
		}

		/*以第一行为初始值*/
		let result = []
		for (var k = 0; k < colWidth.length; k++) {
			result[k] = colWidth[k][0]
			for (let i = 1; i < colWidth[k].length; i++) {
				for (let j = 0; j < colWidth[k][i].length; j++) {
					if (result[k][j]["wch"] < colWidth[k][i][j]["wch"]) {
						result[k][j]["wch"] = colWidth[k][i][j]["wch"]
					}
				}
			}
		}
		// 分别给sheet表设置宽度
		for (var l = 0; l < result.length; l++) {
			ws[l]["!cols"] = result[l]
		}
	}

	/* add worksheet to workbook */
	for (var k = 0; k < header.length; k++) {
		wb.SheetNames.push(ws_name[k])
		wb.Sheets[ws_name[k]] = ws[k]
	}

	var wbout = XLSX.write(wb, {
		bookType: bookType,
		bookSST: false,
		type: "binary"
	})
	saveAs(
		new Blob([s2ab(wbout)], {
			type: "application/octet-stream"
		}),
		`${filename}.${bookType}`
	)
}

调用:

methods: {
    exportFile () {
       const _vm = this;
       const sheet1 = [
         {id: 1, name: 'xiaoming', age: 10},
         {id: 2, name: 'xiaohong', age: 15},
       ]
       const sheet2 = [
         {id: 3, name: 'xiaoming1', age: 30, sex: '女'},
         {id: 4, name: 'xiaohong2', age: 20, sex: '男'},
       ]
       const sheet1Head = ['id', '名字', '年龄']
       const sheet2Head = ['id', '名字', '年龄', '性别']
       const sheet1Filter = ['id', 'name', 'age']
       const sheet2Filter = ['id', 'name', 'age', 'sex']
       let excelDatas = [
                    {
                        tHeader: sheet1Head, // sheet表一头部
                        filterVal: sheet1Filter, // 表一的数据字段
                        tableDatas: sheet1, // 表一的整体json数据
                        sheetName: "sheet1"// 表一的sheet名字
                    },
                    {
                        tHeader: sheet2Head, // sheet表二头部
                        filterVal: sheet2Filter , // 表二的数据字段
                        tableDatas: sheet2, // 表二的整体json数据
                        sheetName: "sheet2"// 表二的sheet名字
                    },
                ]
        this.json2excel(excelDatas, "人员列表", true, "xlsx")
      },
     // 导出excel方法引用
    json2excel(tableJson, filenames, autowidth, bookTypes) {
      const that = this
        //引用插件
      import("。/js/Export3Excel").then(excel => {
        let tHeader = []
        let dataArr = []
        let sheetnames = []
        for (let i in tableJson) {
          tHeader.push(tableJson[i].tHeader)
          dataArr.push(that.formatJson(tableJson[i].filterVal, tableJson[i].tableDatas))
          sheetnames.push(tableJson[i].sheetName)
        }
        excel.export_json_to_excel({
          header: tHeader,
          data: dataArr,
          sheetname: sheetnames,
          filename: filenames,
          autoWidth: autowidth,
          bookType: bookTypes
        })
      })
    }
}

这样就可以根据自己的需求去导出一个sheet或者两个sheet的Excel了!

 

 

 

 

 

posted @ 2019-12-02 17:13  zaijinyang  阅读(1393)  评论(0编辑  收藏  举报