PhpSpreadsheet 小教程

关于 PhpSpreadsheet 简单教程

今天遇到一个问题,涉及 php 与 excel 之间数据转换。之前一直用PHPExcel,他们的开发组不更新了。但是找到了 PhpSpreadsheet

一. 介绍

用纯php编写的库,它提供了一组类,允许您读取和写入不同的电子表格文件格式

支持格式

格式 读取 写入
ods
excel 2007 及以上(xlsx)
excel 97 及以上(xls)
excel 95(xls,传说中的 BIFF 5)
excel 2003(xml,SpreadsheetML)
CSV

环境要求

  • php 5.6 及以上
  • php_zip 支持并启用
  • php_xml 支持并启用
  • php_gd2 支持并启用

安装

> composer require phpoffice/phpspreadsheet

hello world

<?php
require 'vendor/autoload.php';

use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;

$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->setCellValue('A1', 'Hello World !');

$writer = new Xlsx($spreadsheet);
$writer->save('hello world.xlsx');

实例

包中带了实例代码,位置 vendor/phpoffice/phpspreadsheet/samples

> php -S localhost:8000 -t vendor/phpoffice/phpspreadsheet/samples

二. 读取

无需关心文件类型加载,用到了IOFactory

// 文件路径
$inputFileName = './sampleData/example1.xls';

$spreadsheet = \PhpOffice\PhpSpreadsheet\IOFactory::load($inputFileName);

注意:
这不是加载文件的最有效方法, 并且它缺乏在将文件实际读入 Spreadsheet 对象之前以任何方式配置加载器的灵活性。

知道文件类型,可以自己决定使用哪种读取器

// 文件路径
$inputFileName = './sampleData/example1.xls';
/** 创建读取器  **/
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xls();
//    $reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
//    $reader = new \PhpOffice\PhpSpreadsheet\Reader\Xml();
//    $reader = new \PhpOffice\PhpSpreadsheet\Reader\Ods();
//    $reader = new \PhpOffice\PhpSpreadsheet\Reader\Slk();
//    $reader = new \PhpOffice\PhpSpreadsheet\Reader\Gnumeric();
//    $reader = new \PhpOffice\PhpSpreadsheet\Reader\Csv();

$spreadsheet = $reader->load($inputFileName);

当只要读取数据,不要格式时,实例读取器中readDataOnly属性,如下

$inputFileType = 'Xls';
$inputFileName = './sampleData/example1.xls';

$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType);
/**  只要数据  **/
$reader->setReadDataOnly(true);

$spreadsheet = $reader->load($inputFileName);

注意:csv 读取器没有这个属性

多个文件合并为一个对象

$inputFileType = 'Csv';
$inputFileNames = [
    './sampleData/example1.csv',
    './sampleData/example2.csv'
    './sampleData/example3.csv'
];

$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType);

/** 拿到第一个  **/
$inputFileName = array_shift($inputFileNames);

$spreadsheet = $reader->load($inputFileName);

$spreadsheet->getActiveSheet()
    ->setTitle(pathinfo($inputFileName,PATHINFO_BASENAME));

/**  循环读取  **/
foreach($inputFileNames as $sheet => $inputFileName) {
    /**  重新设置工作表索引  **/
    $reader->setSheetIndex($sheet+1);
    /**  把文件当做一个新的工作表载入  **/
    $reader->loadIntoExisting($inputFileName,$spreadsheet);
    /**  设置工作表标题  **/
    $spreadsheet->getActiveSheet()
        ->setTitle(pathinfo($inputFileName,PATHINFO_BASENAME));
}

注意:对多个工作表使用相同的工作表索引不会将文件附加到同一工作表中,而是覆盖先前加载的结果。您无法将多个CSV文件加载到同一工作表中。

转为数组

文件最后会载入到一个对象中,我称为spreadsheet 工作表对象,这个对象中存放着所以工作表集合的信息(数据信息和格式信息、工作表信息等)

$spreadsheet = PhpOffice\PhpSpreadsheet\IOFactory::load("new.xls");

$data = $spreadsheet
            ->getSheet(0) // 指定第一个工作表为当前
            ->toArray();  // 转为数组

// 或者得到全部工作表的数据数组           
$cells=array();
// 工作表对象有迭代器实现
foreach ( $spreadsheet->getWorksheetIterator() as $data ) {
    $cells = $data->toArray();
}

结语

PhpSpreadsheet是非常不错的php的电子表格处理工具类,后续有时间在补上写入和导出

本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由系统于 4年前 自动加精
讨论数量: 5

我们可以理解为phpspredsheet 可以完成花里胡哨的excel 但数据量大时会超出内存 但laravelexcel不会 因为它太丑了 :joy:

4年前 评论
lmaster

@罪人 Laravel-Excel 是对PhpSpreadsheet进行Laravel封装。

PhpSpreadsheet在载入文件时候有可以按块载入,即一个文件可以分成多个部分载入;来解决数据过多导致内存占用更高

4年前 评论

请问如果遇到那种计算工资的表格,导入怎么不导入隐藏的项呢

3年前 评论
lmaster

@iwaters 不好意思才看到,你说的这个事情:隐藏了一列对么?

file 这种隐藏 B 列 对么?

file 隐藏后是 B 看不到,但是 B还在,所以不影响导入吧。

3年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!