vue多sheet表格导出

安装依赖
npm install -S file-saver xlsx
npm install -D script-loader
新建两个js文件(Blob.js和Export2Excel.js)
Blob.j 网上一大堆
Export2Excel.js

/* eslint-disable */
require('script-loader!file-saver');
require('./Blob');
require('script-loader!xlsx/dist/xlsx.core.min');
import XLSX from 'xlsx-style';

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

const defaultCellStyle = {
	font: {
		name: "宋体",
		sz: 12,
		color: {
			auto: 1
		},
	},
	border: {
		color: {
			auto: 1
		},
		top: {
			style: 'thin'
		},
		bottom: {
			style: 'thin'
		},
		left: {
			style: 'thin'
		},
		right: {
			style: 'thin'
		}
	},
	alignment: {
		/// 自动换行
		wrapText: true,
		// 居中
		horizontal: "center",
		vertical: "center",
		indent: 0
	}
};

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] };
			/// 这里生成cell的时候,使用上面定义的默认样式
			const cell = {
				v: data[R][C],
				s: defaultCellStyle
			};
			// if (cell.v == '抵港报') {
			// 	cell.s = {
			// 		alignment: {
			// 			horizontal: 'center',
			// 			vertical: 'center',
			// 			wrapText: true
			// 		}, //设置标题水平竖直方向居中,并自动换行展示
			// 		fill: {
			// 			fgColor: {
			// 				rgb: 'ebebeb'
			// 			} //设置标题单元格的背景颜色
			// 		}
			// 	}
			// }
			// 如果单元格所在的值为空,让其值为---
			if (cell.v == null) {
				cell.v = ' '
			};
			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);

	/*设置worksheet每列的最大宽度*/
	const colWidth = data.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 + 5
				};
			}
		})
	);
	/*以第一行为初始值*/
	let result = colWidth[0];
	colWidth[0][0]['wch'] = 10;
	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;

	/* 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');
}

// 导出多个sheet
export function export2ExcelMultiSheet({
	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))
		})
	}



	// console.log("width", autoWidth)
	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 + 5
							}
						}
					})
				)
			)
		}

		/*以第一行为初始值*/
		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}`
	)
}

使用
项目上使用antd ui库 其他ui库写法稍微有些区别

 // 导出数据
    async exportData() {
      this.loading = true
      let filterVal = this.columns.map((el) => {
        return el.dataIndex
      })
      let th = this.columns.map((el) => {
        return el.title
      })
      let filterVals = this.columnss.map((el) => {
        return el.dataIndex
      })
      let ths = this.columnss.map((el) => {
        return el.title
      })
      let result = [
        {
          tHeader: th, //表头
          filterVal: filterVal,  // 表头对应字段
          tableDatas: this.tableDataList,  //数据
          sheetName: '全部数据', // sheet名称
        },
        {
          tHeader: ths,
          filterVal: filterVals,
          tableDatas: this.reList,
          sheetName: '汇总数据',
        },
      ]
      let obj = {}
       this.shipList.map((el) => {
        if (this.params.imo == el.imo) {
           obj =   el
        }
      })
      // console.log(obj)
      this.json2excel(result, obj.shipName + '~ 停泊油耗', true, 'xlsx')
      this.loading = false
    },

    json2excel(tableJson, filenames, autowidth, bookTypes) {
      var that = this
      import('@/excel/Export2Excel').then((excel) => {
        var tHeader = []
        var dataArr = []
        var sheetnames = []
        for (var i in tableJson) {
          tHeader.push(tableJson[i].tHeader)
          dataArr.push(that.formatJson(tableJson[i].filterVal, tableJson[i].tableDatas))
          sheetnames.push(tableJson[i].sheetName)
        }
        excel.export2ExcelMultiSheet({
          header: tHeader,
          data: dataArr,
          sheetname: sheetnames,
          filename: filenames,
          autoWidth: autowidth,
          bookType: bookTypes,
        })
      })
    },

    // 格式化数据
    formatJson(filterVal, jsonData) {
      return jsonData.map((v) => filterVal.map((j) => v[j]))
    },

猜你喜欢

转载自blog.csdn.net/weixin_45653441/article/details/128643810
今日推荐