vxe-table导出excel插件,即exceljs导出多张图片的坑
使用vxe-table的vxe-img-group组件在单元格可以很好的在web页面渲染多张图片,但是如果使用推荐的第三方导出excel插件plugin-export-xlsx(基于exceljs)的话,则只能导出第一张图片.
搜索全网,没找到类似需求的解决方法,问deepseek,倒是给出了通过配置偏移量实现的方案,但是实际测试才发现坑很大
const exportToExcel = async () => { data.search.rows = 999999 await getDataList() const $table = tableRef.value if ($table) { // 配置exportConfig的sheetMethod方法给 excel单元格添加 多张图片,实际上就是操作exceljs的接口 exportConfig.sheetMethod = async (params) =>{ console.log('配置exportConfig的sheetMethod方法'); const dataList = data.dataList const imageList = dataList[0].beforeRectificationImgsList console.log('图片===',imageList) const { worksheet, workbook } = params // // 1. 调整目标单元格的行高和列宽,为多张图片预留空间 // const targetRow = 4; // 例如,第二行 // const targetCol = 9; // 例如,B列 // worksheet.getRow(targetRow).height = 150; // 设置行高 // worksheet.getColumn(targetCol).width = 30; // 设置列宽 // // // 2. 将图片添加到工作簿 // const imageId1 = workbook.addImage({ // filename: 'http://127.0.0.1:19000/donghai7s/CheckPhotos/2025/10/00_093351948.png', // 替换为你的图片路径 // extension: 'png', // }); // const imageId2 = workbook.addImage({ // filename: 'http://127.0.0.1:19000/donghai7s/CheckPhotos/2025/10/00_093352238.png', // 替换为你的图片路径 // extension: 'png', // }); // // ... 可以添加更多图片 // // // 3. 将图片定位到同一个单元格内的不同位置 // // 获取单元格的起始位置(左上角) // // 注意:ExcelJS 的坐标是从 (1, 1) 开始的 // const cellStartPos = { // col: targetCol, // row: targetRow // }; // // // 定义图片在单元格内的偏移量和尺寸 // worksheet.addImage(imageId1, { // tl: { col: cellStartPos.col, row: cellStartPos.row }, // 定位到单元格左上角 // ext: { width: 50, height: 50 } // 设置图片显示尺寸 // }); // // worksheet.addImage(imageId2, { // tl: { // col: cellStartPos.col + 0.3, // 在单元格内水平偏移(可理解为向右移动) // row: cellStartPos.row + 0.3 // 在单元格内垂直偏移(可理解为向下移动) // }, // ext: { width: 50, height: 50 } // }); // 假设将4张图片排列成 2x2 的网格 const imagesPerRow = 7; // 每行图片数 const imageWidth = 60; const imageHeight = 30; // 获取单元格的起始位置(左上角) // 注意:ExcelJS 的坐标是从 (1, 1) 开始的 const cellStartPos = { col: 8, row: 3 }; // 计算单元格总大小,并据此设置行高列宽 // worksheet.getColumn(9).width = imageWidth * imagesPerRow; // 遍历所有图片,计算每个图片在网格中的位置 for (const image of imageList) { const index = imageList.indexOf(image); console.log(index, image) // const buffer = await fetch(image).then(res => res.arrayBuffer()) // // 2. 将图片添加到工作簿 // const imageId = workbook.addImage({ // buffer, // 替换为你的图片路径 // // }); const buffer1 = await fetch('http://127.0.0.1:19000/donghai7s/CheckPhotos/2025/10/00_093352238.png').then(res => res.arrayBuffer()) const imageId = workbook.addImage({ buffer: buffer1, extension: 'png' }) const rowOffset = Math.floor(index / imagesPerRow*100)/100; // 计算行偏移 console.log('=计算行偏移====',rowOffset) worksheet.addImage(imageId, { tl: { col: cellStartPos.col+ rowOffset, // 水平方向偏移 row: cellStartPos.row // 垂直方向偏移 }, ext: { width: imageWidth, height: imageHeight } }); } } console.log('====开始导出'); await $table.exportData({ type: 'xlsx', useStyle: true }) console.log('====导出完成'); //高级导出 // $table.openExport() } data.search.rows = 10 await getDataList() }
如上图配置exportConfig的sheetMethod方法,这个坑实际上是微软excel的坑,它的列宽是基于字符宽度,也就是不是一个固定的值(并且因为留白之类的还要再多一点,比如默认是8个字符宽度,实际查看是8.23),而exceljs在计算偏移量的时候是把它当做像素计算的(也有说是exceljs自己的一套,见下面参考文章),导致导出后,即使你换算的非常精确,结果却是所有图片挤在单元格左侧的大概三分之一的空间,剩下的都是空白,所以,这种方法是不可行的,只少用exceljs不行,后端导出有可能行吧,不过嫌麻烦没试,根据deepseek的推荐,使用曲线实现的方法:设置成每个单元格一张图片,再设置合并单元格
参考文章:

浙公网安备 33010602011771号