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

如何在ReactJS客户端提取Excel工作表中的浮动图片?

客户端提取Excel浮动图片的可行方案

以下是几种纯客户端(或Node.js环境)实现的方案,无需依赖服务端:

方案1:使用ExcelJS库

ExcelJS原生支持识别工作表中的浮动图片,处理逻辑简单直接:

  1. 安装依赖:
npm install exceljs
  1. 提取图片的代码示例:
const ExcelJS = require('exceljs');
const fs = require('fs');

async function extractFloatingImages(filePath) {
  const workbook = new ExcelJS.Workbook();
  await workbook.xlsx.readFile(filePath);

  // 遍历所有工作表
  for (const worksheet of workbook.worksheets) {
    // 检查当前工作表是否有浮动图片
    if (!worksheet.drawings || worksheet.drawings.length === 0) continue;

    worksheet.drawings.forEach((drawing, idx) => {
      if (drawing.image) {
        // 保存图片到本地
        const savePath = `float_img_${worksheet.name}_${idx}.${drawing.image.extension}`;
        fs.writeFileSync(savePath, drawing.image.buffer);
      }
    });
  }
}

// 调用示例
extractFloatingImages('your_file.xlsx');

方案2:SheetJS结合手动解析XLSX内部结构

SheetJS本身不直接提取浮动图片,但可以借助它读取XLSX的内部文件结构,手动解析绘图相关的XML文件来定位图片:

  1. 安装依赖:
npm install xlsx xml2js
  1. 实现代码:
const XLSX = require('xlsx');
const xml2js = require('xml2js');
const fs = require('fs');

async function extractImagesWithSheetJS(filePath) {
  const workbook = XLSX.readFile(filePath, { type: 'file' });
  const parser = new xml2js.Parser();

  // 遍历工作表对应的绘图文件
  for (const sheetName of workbook.SheetNames) {
    const sheet = workbook.Sheets[sheetName];
    const drawingId = sheet['!drawing'];
    if (!drawingId) continue;

    // 获取绘图XML文件和对应的关系文件
    const drawingXml = workbook.files[`xl/drawings/drawing${drawingId}.xml`].data.toString();
    const relsXml = workbook.files[`xl/drawings/_rels/drawing${drawingId}.xml.rels`].data.toString();

    // 解析关系文件,映射rId到图片路径
    const relsResult = await parser.parseStringPromise(relsXml);
    const rIdMap = {};
    relsResult.Relationships.Relationship.forEach(rel => {
      rIdMap[rel.$.Id] = rel.$.Target;
    });

    // 解析绘图XML,提取图片对应的rId
    const drawingResult = await parser.parseStringPromise(drawingXml);
    const blips = drawingResult['xdr:wsDr']['xdr:twoCellAnchor']?.map(anchor => {
      return anchor['xdr:pic']?.[0]['xdr:blipFill']?.[0]['a:blip']?.[0]['$']['r:embed'];
    }).filter(Boolean);

    // 提取并保存图片
    blips.forEach((rId, idx) => {
      const imgPath = `xl/${rIdMap[rId]}`;
      const imgBuffer = workbook.files[imgPath].data;
      const ext = imgPath.split('.').pop();
      fs.writeFileSync(`sheet_${sheetName}_img_${idx}.${ext}`, imgBuffer);
    });
  }
}

// 调用示例
extractImagesWithSheetJS('your_file.xlsx');

方案3:直接解析XLSX压缩包

XLSX本质是ZIP格式文件,可通过JSZip直接解压后读取内部的绘图和媒体文件:

  1. 安装依赖:
npm install jszip xml2js
  1. 实现代码:
const JSZip = require('jszip');
const xml2js = require('xml2js');
const fs = require('fs');

async function extractImagesFromZip(filePath) {
  const zipData = fs.readFileSync(filePath);
  const zip = await JSZip.loadAsync(zipData);
  const parser = new xml2js.Parser();

  // 遍历所有绘图文件
  const drawingFiles = Object.keys(zip.files).filter(path => path.startsWith('xl/drawings/drawing') && path.endsWith('.xml'));
  
  for (const drawingPath of drawingFiles) {
    // 读取绘图XML和对应的关系文件
    const drawingXml = await zip.file(drawingPath).async('string');
    const relsPath = drawingPath.replace('.xml', '.xml.rels');
    const relsXml = await zip.file(relsPath).async('string');

    // 解析关系文件
    const relsResult = await parser.parseStringPromise(relsXml);
    const rIdToTarget = relsResult.Relationships.Relationship.reduce((map, rel) => {
      map[rel.$.Id] = rel.$.Target;
      return map;
    }, {});

    // 解析绘图XML获取图片rId
    const drawingResult = await parser.parseStringPromise(drawingXml);
    const imageRIds = drawingResult['xdr:wsDr']['xdr:twoCellAnchor']?.reduce((ids, anchor) => {
      const blip = anchor['xdr:pic']?.[0]['xdr:blipFill']?.[0]['a:blip']?.[0];
      if (blip?.$?.['r:embed']) ids.push(blip.$['r:embed']);
      return ids;
    }, []) || [];

    // 提取并保存图片
    imageRIds.forEach((rId, idx) => {
      const imgTarget = rIdToTarget[rId];
      if (!imgTarget) return;
      zip.file(`xl/${imgTarget}`).async('nodebuffer').then(imgBuffer => {
        const ext = imgTarget.split('.').pop();
        fs.writeFileSync(`extracted_img_${idx}.${ext}`, imgBuffer);
      });
    });
  }
}

// 调用示例
extractImagesFromZip('your_file.xlsx');

以上方案均支持在Node.js环境(客户端侧运行)或浏览器环境(调整文件读取逻辑为File API)实现,无需依赖服务端。

内容的提问来源于stack exchange,提问作者Mohsin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 16:12:47