使用 PhpSpreadsheet 实现读取写入 Execl


前言

这两天需要做一个支持读写微软办公软件的功能模块.最底下会说下自己下一步的想法,我先找了PhpSpreadheet这个第三方的扩展包,功能很完善,是一个纯PHP编写的库,看了官方文档,目前支持XLS,XML,XLSX,ODS,SLK,Gnumeric,CSV以及HTML.

软件支持

    需要满足以下条件:

  1. PHP5.6及以上版本
  2. PHP扩展php_zip已开启
  3. PHP扩展php_xml已开启
  4. 启用PHP扩展php_gd2(如果没有编译)

安装

进入自己的项目目录,使用composer安装

composer require phpoffice/phpspreadsheet

编写电子表格最简单的一个方法

<?php

require'vendor/autoload.php';
usePhpOffice\PhpSpreadsheet\Spreadsheet;
usePhpOffice\PhpSpreadsheet\Writer\Xlsx;

 $spreadsheet = new Spreadsheet();
 $sheet = $spreadsheet->getActiveSheet();
 $sheet->setCellValue('A1', 'Hello World !');$writer = new Xlsx($spreadsheet);
 $writer->save('hello world.xlsx');

读取文件

可以使用PhpSpreadsheet的IOFactory识别文件类型并加载它,

$inputFileName = './sampleData/example1.xls';
$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($inputFileName);

此方法会在执行加载之前测试当前文件,为了防止恶意文件,比如说当前文件实际上是CSV文件或者包含HTML标记,但是已经给出了.xls的扩展名,它会拒绝用于.xls的加载器,而使用其他的加载器去检测当前文件.

读取文件实例

<?php

use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\IOFactory;



 public function actionGetExcel()
    {
        $whatTable = 0;
        $filename = 'cc.xlsx';
        /**  Identify the type of $inputFileName  **/
        $inputFileType = \PhpOffice\PhpSpreadsheet\IOFactory::identify($filename); 
        /**  Create a new Reader of the type that has been identified  **/
        $reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType); //实例化阅读器对象。
        $spreadsheet = $reader->load($filename);  //将文件读取到到$spreadsheet对象中
        $worksheet = $spreadsheet->getActiveSheet();   //获取当前文件内容
        $sheetAllCount = $spreadsheet->getSheetCount(); // 工作表总数
        for ($index = 0; $index < $sheetAllCount; $index++) {   //工作表标题
            $title[] = $spreadsheet->getSheet($index)->getTitle();
        }

        $sheet = $spreadsheet->getSheet($whatTable); // 读取第一個工作表

        $highest_row = $sheet->getHighestRow(); // 取得总行数

        $highest_column = $sheet->getHighestColumn(); ///取得列数  字母abc...
        //
        $highestColumnIndex = Coordinate::columnIndexFromString($highest_column);  //转化为数字;
        for ($i = 1; $i <= $highestColumnIndex; $i++) {
            for ($j = 1; $j <= $highest_row; $j++) {

//                $conent = $sheet->getCellByColumnAndRow($i, $j)->getValue();
                $conent = $sheet->getCellByColumnAndRow($i, $j)->getCalculatedValue();

                $info[$j][$i] = $conent;
            }
        }
      var_dump($info);
    }

这里我屏蔽掉了

$conent = $sheet->getCellByColumnAndRow($i, $j)->getValue();

因为我们execl中的表格的值不一定就是手动书写上去的,有些是通过单元格之间的计算得出的结果,这时候直接获取值我们得到的只是一个运算公式的字符串,比如下图中的 '=SUM($i,$j)' 这时候我们需要使用包中支持execl运算的计算引擎来为我们处理运算公式,并获取计算之后的值.

b8513b2c18ef98c6c62efaa483786aa2.png

最后变成一个二维数组的数据(行列),然后渲染就实现了简单的读功能了,但是这里还有问题

  • execl表中之前有些单元格有样式的,暂时没有从那一坨东西中找到.
  • 有些公式之前还写了东西,比如图中的$,或者负数了就-$.......,你计算出来之后只是一个值,这一块也需要处理
  • 表格中的图片,图处理.....
  • 编辑修改execl

还有很多很多的功能可以通过官方文档查看:https://phpspreadsheet.readthedocs.io/en/latest/.

别的方案(我暂时没去搭建)

不管你把这个包用的再好,你还是不能完美的实现客户端在没有安装微软office的情况下实现在线查看在线直接编辑的文件.看了一些文档查了点资料可以搭建office web apps的服务来满足这样的需求.

需要两台主机.主机的系统必须是windwos Server. 一台主机要安装office Online就可以理解提供office的在线服务,另一台作为域控制器(好专业的名词),就是由这个主机专门去管理office Online主机,可以去微软官网文档具体看下操作,如果有人已经搭建了,希望能分享一下.

官网文档:https://docs.microsoft.com/en-us/webappsserver/office-web-apps-server-overview


Vote Vote Cancel Collect Collect Cancel

<< 上一篇: 在 Laravel 5 中使用 Laravel Excel 实现 Excel/CSV 文件导入导出功能

>> 下一篇: 在 Laravel 中使用 Laravel Searchy 扩展包实现基于数据库的轻量级搜索功能