Angular项目中读取含图片列的Excel文件问题
Angular读取Excel嵌入图片问题解决方案
问题场景
我在开发Angular应用时,上传包含文本和嵌入图片的Excel文件后,通过xlsx库读取只能获取文本数据,单元格里的图片完全无法读取。当前使用的模板和代码如下:
组件模板
<form [formGroup]="uploadForm" (ngSubmit)="Excel_Upload()" > <a id="excel_upload_label">Upload Excel</a> <input type="file" (change)="onEx_FileChange($event)" multiple="false"> <button type="submit" id="excel_upload_button">Upload Properties</button> </form>
读取逻辑代码
onEx_FileChange(evt : any){ const target : DataTransfer = <DataTransfer>(evt.target); if(target.files.length !== 1){ alert("Multiple File upload"); } const reader : FileReader = new FileReader(); reader.onload = (e : any) =>{ const bstr: string = e.target.result; const wb: XLSX.WorkBook = XLSX.read(bstr, {type: 'binary'}); const wsname : string = wb.SheetNames[0]; const ws: XLSX.WorkSheet = wb.Sheets[wsname]; this.data = (XLSX.utils.sheet_to_json(ws, {header:1})); console.log(this.data); // 仅能看到文本数据 }; reader.readAsBinaryString(target.files[0]); }
问题原因
默认情况下,XLSX.utils.sheet_to_json()仅提取单元格的文本内容,不会解析Excel中独立存储的嵌入图片。图片在Excel的结构中属于单独的资源对象,需要额外读取和关联到对应单元格。
解决方案
修改读取逻辑,先提取Excel中的图片资源,再将图片数据与对应单元格位置关联。以下是修改后的完整代码:
onEx_FileChange(evt: any) { const target: DataTransfer = <DataTransfer>(evt.target); if (target.files.length !== 1) { alert("请勿上传多个文件"); return; } const reader: FileReader = new FileReader(); reader.onload = (e: any) => { const bstr: string = e.target.result; // 读取时启用相关配置,确保能获取图片元数据 const wb: XLSX.WorkBook = XLSX.read(bstr, { type: 'binary', cellStyles: true, cellHTML: true }); const wsname: string = wb.SheetNames[0]; const ws: XLSX.WorkSheet = wb.Sheets[wsname]; // 读取文本数据 this.data = XLSX.utils.sheet_to_json(ws, { header: 1 }); // 提取并关联图片数据 const excelImages = this.extractSheetImages(wb, wsname); excelImages.forEach(img => { // 解析图片左上角所在的单元格,转换为行列索引 const cellPos = XLSX.utils.decode_cell(img.tl); const rowIdx = cellPos.r; const colIdx = cellPos.c; // 将图片base64数据赋值到对应单元格位置 if (this.data[rowIdx]) { this.data[rowIdx][colIdx] = `data:${img.type};base64,${img.data}`; } }); console.log(this.data); // 现在能看到文本和图片的base64数据 }; reader.readAsBinaryString(target.files[0]); } // 提取指定工作表中的图片资源 extractSheetImages(wb: XLSX.WorkBook, sheetName: string): Array<{tl: string, type: string, data: string}> { const images = []; // 检查WorkBook中是否存在图片存储节点 if (wb.Workbook?.WP?.[sheetName]?.Images) { wb.Workbook.WP[sheetName].Images.forEach(img => { images.push({ tl: img.tl, // 图片左上角单元格地址(如D2) type: img.Type, // 图片MIME类型(如image/png) data: img.Data // 图片base64编码数据 }); }); } return images; }
额外说明
- 转换后的图片为base64格式,可直接在
<img>标签中使用,例如:<img [src]="data[rowIndex][colIndex]"> - 该方案仅支持
.xlsx格式文件,旧版.xls格式的图片读取需要额外处理(xlsx库对旧格式图片支持有限) - 如果图片是悬浮在单元格上方而非嵌入单元格,需要调整位置匹配逻辑(根据图片的坐标计算对应单元格)
内容的提问来源于stack exchange,提问作者Muhammad Hassan
相关产品推荐
相关产品推荐

