使用excelJs处理文件导出,并封装aoa转excel的方法

最近在做一些纯前端导出的功能,要求excel需要有一些格式、样式的调整,当时想使用excel模板然后读取模板从种写数的,通过设置模版的特殊位置字符,读取模板进行直接替换。发现由于动态数据的局限性,还是打算直接使用js去生成一个excel文件。开始使用的xlsx.js进行开发,利用xlsx-style进行样式设置,xlsx支持的api的能够实现的功能相对比较多的,(由于xlsx-style引用报错问题,可以使用real-xlsx-style代替),在实际开发中,虽然xlsx实现了很多功能,但是发现xlsx-style设置单元格超链接设置不上、并且每个设置了样式的单元格,内容都会被初始化,(文档太少了,不建议使用,可以研究研究),后面决定使用excel.js进行导出。

通过aoa 数据转换为excel文件

const aoa_to_excel = (aoa, opts) => {
	opts = opts || {};
	const sheetName = opts.sheetName || "sheet1";
	const workbook = new ExcelJS.Workbook();
	const ws = workbook.addWorksheet(sheetName, opts.sheetConfig);
	for(let i = 0, length = aoa.length; i < length ; i++){
		for(let j = 0, len = aoa[i].length; j < len; j++ ) {
			const cell = ws.getRow(i + 1).getCell(j + 1);
			cell.value = aoa[i][j];
			// 设置地址为超链接
			if(opts.openHrefLink && typeof aoa[i][j] === 'string' && /^(http:|https:)/.test(aoa[i][j])){

				cell.value = {
					text: aoa[i][j],
					hyperlink: aoa[i][j],
					tooltip: aoa[i][j]
				};
				cell.font = { underline: true, color: { argb: 'FF315EFB'} }

			}
	
			// 设置默认样式
			if(opts.defaultCellStyle) {
				const defaultStyle = opts.defaultCellStyle;
				if(defaultStyle.alignment) {
					cell.alignment = { ...defaultStyle.alignment, ...(cell.alignment || {})}
				}
				if(defaultStyle.border) {
					cell.border = { ...defaultStyle.border, ...(cell.border || {})}
				}
				if(defaultStyle.font) {
					cell.font = { ...defaultStyle.font, ...(cell.font || {})}
				}
				if(defaultStyle.fill) {
					cell.fill = { ...defaultStyle.fill, ...(cell.fill || {})}
				}
			}
			if(typeof opts.onCustomCell === 'function') {
				opts.onCustomCell(cell, i + 1, j + 1)
			}
		}
	}


	// 处理列
	if(opts.columnsConfig instanceof Array) {
		ws.columns = (ws.columns || []).map((v, index) => {
			const config = opts.columnsConfig[index] || {};
			return { ...v, ...config }
		})
	}

	// 处理合并
	if(opts.merges instanceof Array) {
		opts.merges.forEach(item => {
			if(item instanceof Array && item.length <= 2) {
				ws.mergeCells(...item)
			}else if(typeof item === 'string') {
				ws.mergeCells(item)
			}
		})
	}

	// 下载文件
	workbook.xlsx.writeBuffer().then((buffer) => {
		const fileName = opts.fileName || sheetName + '.xlsx';
		let blob = new Blob([buffer], { type: "application/octet-stream" });
		download(URL.createObjectURL(blob), fileName);

	});
}

文件下载

下面的文件下载针对创建a标签然后通过click点击的方式更有效

const download = (url, saveName) => {
  if (typeof url === "object" && url instanceof Blob) {
    url = URL.createObjectURL(url); // 创建blob地址
  }

  let aLink = document.createElement("a");
  aLink.href = url;
  aLink.download = saveName || ""; // HTML5新增的属性,指定保存文件名,可以不要后缀,注意,file:///模式下不会生效
  let event;
  if (window.MouseEvent) event = new MouseEvent("click");
  else {
    event = document.createEvent("MouseEvents");
    event.initMouseEvent(
      "click",
      true,
      false,
      window,
      0,
      0,
      0,
      0,
      0,
      false,
      false,
      false,
      false,
      0,
      null
    );
  }
  aLink.dispatchEvent(event);
}

调用

const aoa = [
	["测试1",  null, "测试2", null],
	["测试3",  null, "测试4", null],
	[null,  null, null, null], // 空行
	// …otherAoa
];

const configOpts = {
	fileName: ‘附件名称.xlsx',
	openHrefLink: true, // 开启自动匹配带http、https开头的地址为超链接
	defaultCellStyle: { // 默认样式
    	font: { name: '宋体', size: 10, color: 'FFFF00' },
    	alignment: { vertical: 'top', horizontal: 'left', wrapText: false, indent: 0 },
    	border: {
        	top: {style:'thin'},
        	left: {style:'thin'},
        	bottom: {style:'thin'},
        	right: {style:'thin'}
    	},
	},
	columnsConfig: [ // 列配置
    	{ width: 15 },
   	 	{ width: 26 },
    	{ width: 50 },
    	{ width: 15 },
	],
	merges: [ 'B1:C1', 'E1:F1', 'B2:C2', 'E2:F2', 'B3:F3' ], // 需要合并单元格
	onCustomCell: (cell, row, cell) => { // 自定义cell回调
		if(row === 4) {
			cell.fill = { type: 'pattern', pattern: 'solid', fgColor: { argb: "FFFFFF00" } 	};
		}
		if( cell === 1 && (cell > 4 && cell % 4 === 1)) {
			cell.font = { name: '宋体', sz: 10, color: { argb: "FFFF0000" }}
		}
	}
}
excelTool.aoa_to_excel(aoa, configOpts) // 导出文件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值