前端excel导出图片
此封装可以自定义图片大小,在excel中换行
一、开发背景
有了上一次的excel导出文字,客户还是不满足,又要把所有图片放到excel里,一目了然。
还好,上一次的插件exceljs支持导出图片。
二、封装
1、放在全局
// exceljs // github: https://github.com/exceljs/exceljs/tree/v3.10.0 const ExcelJS = require("exceljs"); import FileSaver from "file-saver"; const { i18n } = require("@/utils/i18n.js"); import BUSINESS_CONFIG from "@/business_config.js"; require("script-loader!xlsx/dist/xlsx.core.min"); import { searchFileByTrans } from "@/api/receipts/receiptsCommon.js"; const twoHeaderRows = 65534; const oneHeaderRows = 65535; export default { install(Vue) { Vue.prototype.$exportImage = async function ( trans_no, trans_type, fileName, fileType ) { // 工作表下标 var sheetIndex = 0; // 图片占左边距离 var width = 0; // 创建工作簿 var workbook = new ExcelJS.Workbook(); // 设置工作簿属性 workbook.creator = "Me"; workbook.lastModifiedBy = "Her"; workbook.created = new Date(1985, 8, 30); workbook.modified = new Date(); workbook.lastPrinted = new Date(2016, 9, 27); // 将工作簿日期设置为 1904 年日期系统 workbook.properties.date1904 = true; // 所有工作表 var worksheetAll = []; // 添加工作表 worksheetAll.push(workbook.addWorksheet(`Sheet${sheetIndex + 1}`)); let imageList = await getImageAssets(trans_no, trans_type); console.log("获取图片资源", imageList); imageList = await downLoadAll(workbook, imageList); console.log("获取图片属性", imageList); addImageToExcel(worksheetAll, sheetIndex, imageList, width); exportExcelImage(workbook, fileName, fileType); this.$store.commit("saveLoadShow", false); }; }, };
2、获取图片资源
这里一定要用同步代码async await等图片回来了,我们再去操作导出。
sort就是数组排序,要按后端返回的document_name字段排序,各位看官可以根据自己的业务需求自行处理。
// 获取图片资源 function getImageAssets(trans_no, trans_type) { return new Promise((resolve, reject) => { searchFileByTrans(trans_no, trans_type).then(async (res) => { if (res.success) { let imageList = res.data.sort((a, b) => a.document_name.localeCompare(b.document_name) ); resolve(imageList); } else { this.$message.error(res.message); } }); }); }
3、并行下载所有图片
// 并行下载所有图片 async function downLoadAll(workbook, imageList) { await Promise.all( imageList.map(async (item, index) => { return downLoadImage(workbook, item); }) ); return imageList; } // 下载图片 async function downLoadImage(workbook, item) { let imageUrl = `${window.location.origin}/api/common/download?resource=${item.file_path}`; // 通过网络请求拿到图片buffer let imageId = await fetch(imageUrl) .then((res) => res.arrayBuffer()) .then((buffer) => { const imageBuffer = Buffer.from(buffer); var imageId = workbook.addImage({ buffer: imageBuffer, extension: item.file_path.split(".")[1], }); return imageId; }); let image = await scaleImg(imageUrl); // 把id和宽高记录在item item.imageId = imageId; item.width = image.width; item.height = image.targetHeightPx; }
4、设置图片的大小
这里我设置的是5cm高,宽度自适应
// 拿到图片宽高、然后设置高度5cm function scaleImg(imageUrl) { const img = new Image(); img.src = imageUrl; return new Promise((resolve) => { img.onload = async () => { let targetHeightPx = (5 * 96) / 2.54; // 四舍五入取整 targetHeightPx = Math.round(targetHeightPx); // 计算缩放比例 const scale = targetHeightPx / img.height; const width = img.width * scale; console.log("宽:", width, "高", targetHeightPx, "比例", scale); resolve({ width, targetHeightPx }); }; }); }
5、把图片放进excel
根据插件描述,需要一个每个图片都要一个imageId,这里我们在下载图片的时候已顺便获取
// 把图片添加到excel function addImageToExcel(worksheetAll, sheetIndex, imageList, width) { let rowIndex = 0; imageList.forEach((item) => { // 开始列 item.startCol = width; // 一个单元格的宽度约为72,加多一列 width = width + Math.ceil(item.width / 72) + 1; // 名称开始行,从A2开始,5cm高度占10行,所以名称放在12 24 行 let nameRow = (rowIndex + 1) * 12; // 添加图片,图片放在2,14,26行,对应下标1,13,25 worksheetAll[sheetIndex].addImage(item.imageId, { tl: { col: item.startCol, row: 12 * rowIndex + 1 }, ext: { width: item.width, height: item.height }, }); // 换行 if (width > 15) { width = 0; rowIndex += 1; } // 名称开始列 let start = String.fromCharCode("A".charCodeAt() + item.startCol); // 添加图片名称 document_name var cell = worksheetAll[sheetIndex].getCell(`${start}${nameRow}`); cell.value = item.document_name.split(".")[0]; cell.style.font = { name: "宋体", family: 4, size: 10, }; }); }
6、下载excel
转成bold,用FileSaver插件下载,和之前的导出excel一样的操作
// 导出 async function exportExcelImage(workbook, fileName, fileType) { // 转成buffer const buffer = await workbook.xlsx.writeBuffer(); // MIME 类型 var type = "application/vnd.openxmlformats"; if (fileType == ".xls") { type = "application/vnd.ms-excel"; } // file-saver在保存文件时,需要把Buffer/Blob转换为Blob URL const blob = new Blob([buffer], { type }); var defaultTitle = fileName || i18n.t("列表"); if (fileType == ".xls") { FileSaver.saveAs(blob, `${defaultTitle}.xls`); } else { FileSaver.saveAs(blob, `${defaultTitle}.xls`); } }
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理!
部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理!
图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!