咔片PPT · AI自动生成演示文稿,模板丰富、排版精美 讯飞智文 · 一键生成PPT和Word,高效应对学习与办公

1、一般后端直接返回二进制文件流,前端直接处理文件流下载就行了

<style lang="stylus" scoped=""> .v-download-excel display inline-block .v-download-excel-btn padding 0 8px background #fff border 1px solid #1890FF color #1890FF height 24px border-radius 4px box-shadow none </style>

2、前端直接根据表格数据导出

下载速度较快,前端可以直接处理要下载的数据,唯一不足图片样式不能自适应,导出来不咋美观

function tableToExcel(colums = [], data = [], name = '表格') { // 列标题 let head = colums.reduce((pev, cur) => { pev += `${cur.title}` }, '') + '' let tbody = '' for (let i = 0; i < data.length; i++) { let g = data[i] let tds = '' for (let j = 0; j < colums.length; j++) { let key = colums[j].key let td = g[key] // 图片链接 if (key === 'pictureUrl' || key === 'imageUrl' || key === 'imgUrl' || key === 'imageSrc' || key === 'imgSrc') { let imgNode = td ? `` : '' tds += imgNode } else { tds += `${td}` } } tbody += `${tds}` } let str = head + tbody // 头部跟身体内容连接 // Worksheet名 let worksheet = name let uri = 'data:application/vnd.ms-excel;base64,' // 下载的表格模板数据 let template = ` ${str}

` // 下载模板 let url = uri + window.btoa(unescape(encodeURIComponent(template))) downloadExcel(url) } function downloadExcel(path) { const a = document.createElement('a') a.setAttribute('download', '我的表格.xlsx') a.setAttribute('href', path) document.body.appendChild(a) a.click() document.body.removeChild(a) }

3、借助第三方插件 exceljs

可以动态获取到每个图片的宽高,样式比较美观,但是因为前端遍历请求了一遍所有图片来获取宽高,速度较慢

// npm i exceljs function exportExcel(colums = [], data = [], seetName = '表格') { const tableData = colums.reduce((pev, cur, index) => { if (cur.key === 'pictureUrl' || cur.key === 'imageUrl' || cur.key === 'imgUrl' || cur.key === 'imageSrc' || cur.key === 'imgSrc') { pev.img.push({ key: cur.url, index, }) } return pev }, { img: [] }) const workbook = new ExcelJS.Workbook() const worksheet = workbook.addWorksheet(seetName) worksheet.columns = colums worksheet.getRow(1).font = { size: 13, bold: true } worksheet.getRow(1).border = { top: { style: 'thin' }, left: { style: 'thin' }, bottom: { style: 'thin' }, right: { style: 'thin' }, } worksheet.getRow(1).fill = { bgColor: { rgb: '#a6edaf' }, } let promiseList = [] data.map(async (m, i) => { worksheet.addRows([m]) let worksheetRow = worksheet.getRow(i + 2) worksheetRow.border = { top: { style: 'thin' }, left: { style: 'thin' }, bottom: { style: 'thin' }, right: { style: 'thin' }, } if (tableData.img.length) { for (let k = 0; k < tableData.img.length; k++) { const curKey = tableData.img[k].key const curIndex = tableData.img[k].index if (m[curKey]) { let pro = loadImg(m[curKey]) promiseList.push(pro) pro.then(img => { let height = (180 / img.width) * img.height const imageId = workbook.addImage({ base64: img.base64, extension: 'png', }) worksheet.addImage(imageId, { tl: { col: curIndex + 0.1, row: i + 1 + 0.3 }, ext: { width: 180, height }, }) worksheetRow.height = (height * 72) / 96 + 10 worksheetRow.alignment = { vertical: 'middle' } }) } } } }) if (promiseList.length) { Promise.all(promiseList).then(async () => { const buffer = await workbook.xlsx.writeBuffer() const blob = new Blob([buffer]) downloadExcel(window.URL.createObjectURL(blob)) }) } else { const buffer = await workbook.xlsx.writeBuffer() const blob = new Blob([buffer]) downloadExcel(window.URL.createObjectURL(blob)) } } function downloadExcel(path) { const a = document.createElement('a') a.setAttribute('download', '我的表格.xlsx') a.setAttribute('href', path) document.body.appendChild(a) a.click() document.body.removeChild(a) } function image2Base64(img) { let canvas = document.createElement('canvas') canvas.width = img.width canvas.height = img.height let ctx = canvas.getContext('2d') ctx.drawImage(img, 0, 0, img.width, img.height) let dataURL = canvas.toDataURL('image/png') return dataURL } function loadImg(url) { return new Promise((resolve, reject) => { const img = new Image() let base64 = '' // 解决跨域 img.src = url + `${url.includes('?') ? '&' : '?'}` + new Date().valueOf() img.setAttribute('crossOrigin', 'anonymous') img.onload = () => { base64 = image2Base64(img) resolve({ base64, height: img.height, width: img.width, }) } img.onerror = (e) => { reject(e) } }) }

直接导出和用exceljs插件(右)导出对比