如何获取Excel单元格中存在的图像?

如何解决如何获取Excel单元格中存在的图像?

我需要阅读单元格中显示的图像,我知道如何阅读图纸中的图纸,但是getDrawingCollection()仅适用于图纸。是否有任何功能可以在获取数据时提供单元格中存在的图像。以下代码用于获取工作表数据。

$spreadsheet = IOFactory::load($inputFileName);
  $worksheet = $spreadsheet->setActiveSheetIndex(2);
  foreach ($worksheet->getRowIterator() as $row) {      
      $cellIterator = $row->getCellIterator();
      $cellIterator->setIterateOnlyExistingCells(FALSE); 
      foreach ($cellIterator as $cell) {
          echo $cell->getValue();
      }          
  }

如果问题是重复的,我很乐意将其删除。

解决方法

我认为它没有任何功能,但是您可以执行以下操作:

foreach ($worksheet->getDrawingCollection() as $drawing) {
    $drawings[$drawing->getCoordinates()] = $drawing;
}
// then find your image using your cell coordinates
$image = $drawings[$cell->getCoordinates()];

// or
foreach ($worksheet->getDrawingCollection() as $drawing) {
    if($drawing->getCoordinates() == $cell->getCoordinates()){
        // or do your stuff here
    }
}
,

我怀疑这是PHPSpreadsheet team的蓄意设计决定,因为您不能真的将图像插入Excel的单元格中-您可以将图像锁定在单元格上方(这样当您调整行/列的大小时,图像停留在该单元格上。无论如何,出于您的目的,这是学术性的。

好,所以我们只能在电子表格级别访问图形。幸运的是,我们可以获取图形的坐标..因此,我们可以在此数据之上建立一个索引,以便为您提供所需的访问权限。

class WorksheetDrawingExt {
    private array $idx=[];

    /**
     * Upon construction will build an index drawings and their locations
     */
    public function __construct(PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $ws) {
        $this->createDrawingIndex($ws);
    }

    private function addDrawingToCell($coord,$drawing) {
        if (array_key_exists($coord,$this->idx)) {
            //There's already one image here - append a new
            $this->idx[$coord][]=$drawing;
        } else {
            //No images so far,setup the base array
            $this->idx[$coord]=[$drawing];
        }
    }

    private function createDrawingIndex($ws) {
        $drawings=$ws->getDrawingCollection();
        foreach ($drawings as $drawing) {
            $coord=$drawing->getCoordinates();//Inconsistent plural!
            $this->addDrawingToCell($coord,$drawing);
        }
    }

    /**
     * Get all drawings for a cell (always returns an array even if there's 1 or less images)
     */
    public function drawingsForCell(PhpOffice\PhpSpreadsheet\Cell\Cell $cell):array {
        return $this->drawingsForCoordinate($cell->getCoordinate());
    }

    /**
     * Get all drawings at the given coordinate (always returns an array even if there's 1 or less images)
     */
    public function drawingsForCoordinate(string $coordinate):array {
        if (array_key_exists($coordinate,$this->idx)) {
            return $this->idx[$coordinate];
        } else {
            return [];
        }
    }
}

您需要为您访问的每个工作表创建这些对象之一,然后使用drawingsForCoordinatedrawingsForCell是您关心的方法。那么您如何使用它呢?遍历电子表格时,您可以向该对象询问与单元格有关的图形:

$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($file);
$ws = $spreadsheet->getActiveSheet();
//Build the new index of drawings:
$wsExt=new WorksheetDrawingExt($ws);

foreach ($ws->getRowIterator() as $row) {      
    $cellIterator = $row->getCellIterator();
    $cellIterator->setIterateOnlyExistingCells(FALSE); 
    foreach ($cellIterator as $cell) {
        //Report the coord:
        $coord=$cell->getCoordinate();
        echo $coord.': ';
        //Report the content 
        echo $cell->getValue();
        //Report images - our new feature in action
        $ds=$wsExt->drawingsForCoordinate($coord);
        //$ds=$wsExt->drawingsForCell($cell);
        foreach($ds as $d) echo $d->getPath().',';
        echo "\n";
    }
} 

我已经稍微更改了您的代码,以表明我们当前正在使用的单元格坐标。出于显示目的,我输出了绘图路径(仅当它不是\PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing时存在)。您可以使用$wsExt->drawingsForCoordinate($coord);(活动)或$wsExt->drawingsForCell($cell);(注释)访问该单元格的所有图形。

因为出于您的目的,您希望访问图形-我选择在WorksheetDrawingExt创建时创建索引。但是,如果可能不总是使用图形(但始终会构建新类),则最好将索引创建与第一次使用drawingsFor*绑定在一起-我将其保留为练习读者。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 <select id="xxx"> SELECT di.id, di.name, di.work_type, di.updated... <where> <if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 <property name="dynamic.classpath" value="tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams['font.sans-serif'] = ['SimHei'] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -> systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping("/hires") public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate<String
使用vite构建项目报错 C:\Users\ychen\work>npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-