You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 04:45:35