Thinkphp5中使用PhpSpreadsheet实现excel的导入导出

一、PhpSpreadsheet 介绍
1.为什么要使用 PhpSpreadsheet

由于 PHPExcel 已经不再维护,所以推荐使用 PhpSpreadsheet 来实现在 Thinkphp5 中实现 excel 的导入或导出功能,PhpSpreadsheet 是一个用 php 编写的库,并引入了命名空间,PSR 规范等。这里简单介绍下 PhpSpreadsheet 在Thinkphp5 框架中的使用方法。

2.使用环境

PHP5.6 或更高版本,推荐 PHP7
支持 php_zip 扩展
支持 php_xml 扩展
支持 php_gd2 扩展

3.PhpSpreadsheet 特性

支持读取 .xls,.xlsx,.html,.csv 等格式文件,支持写入导出 .xls,.xlsx,.html,.csv,.pdf 格式文件。提供丰富的 API,提供单元格样式设置、Excel 表格属性设置、图表设置等等诸多功能。使用 PhpSpreadsheet 完全可以生成一个外观结构都满足你的Excel 表格文件。卓越的性能,尤其在 PHP7 上表现优异,比 PHPExcel 强大很多。

4.PhpSpreadsheet 的官网地址

PhpSpreadsheet 官网地址

5.Thinkphp5 中安装 PhpSpreadsheet

在 composer.json 中使用阿里云中国镜像

    "repositories": {
        "packagist": {
            "type": "composer",
            "url": "https://mirrors.aliyun.com/composer/"
        }
    }
//默认会安装最新版本
composer require phpoffice/phpspreadsheet

运行完成以后就等待安装完成
Thinkphp5中使用PhpSpreadsheet实现excel的导入导出_第1张图片在 composer.json 文件中可以看到安装的版本信息

    "require": {
        "php": ">=7.1",
        "topthink/framework": "5.1.*",
        "phpoffice/phpspreadsheet": "^1.15"
    },

在 vendor 目录下可以看到生成的相关文件夹
Thinkphp5中使用PhpSpreadsheet实现excel的导入导出_第2张图片

二、实际使用
1.引用

新建一个控制器 TestexcelController.php


//测试 PhpSpreadsheet 中的功能
namespace app\daba\controller;

use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\IOFactory;
use think\Controller;
use think\Request;
2.获取 excel 动态工作簿

getActiveSheet()

    /**
     * @param Request $request
     * @throws \PhpOffice\PhpSpreadsheet\Exception
     * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
     */
    public function handleExcel(Request $request)
    {
        //实例化Spreadsheet对象
        $spreadsheet = new Spreadsheet();
        //获取活动工作薄
        $sheet = $spreadsheet -> getActiveSheet();
    }
3.获取单元格

方式一:getCell
方式二:getCellByColumnAndRow

        //获取单元格
        $cellA = $sheet -> getCell('A1');//获取A1单元格
        //获取单元格
        $cellB = $sheet -> getCellByColumnAndRow(1, 2);//获取坐标为1,2也就是A2单元格
4.设置单元格的值

setValue()

        //获取单元格
        $cellA = $sheet -> getCell('A1');
        //设置单元格值
        $cellA -> setValue('囚牛');
5.获取单元格值

getValue() 获取单元格值
getCoordinate() 获取单元格坐标

        //获取单元格
        $cellA = $sheet -> getCell('A1');
        //设置单元格值
        $cellA -> setValue('囚牛');
        echo('值: '.$cellA -> getValue());
        echo('坐标: '.$cellA -> getCoordinate());
值: 囚牛坐标: A1
6.excel 表格的保存和下载

//测试 PhpSpreadsheet 中的功能
namespace app\daba\controller;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Style\Color;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
use PhpOffice\PhpSpreadsheet\Style\Alignment;
use think\Controller;
use think\Request;
class TestexcelController extends Controller
{
    /**
     * @param Request $request
     * @throws \PhpOffice\PhpSpreadsheet\Exception
     * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
     */
    public function handleExcel(Request $request)
    {
        //实例化Spreadsheet对象
        $spreadsheet = new Spreadsheet();
        //获取活动工作薄
        $sheet = $spreadsheet -> getActiveSheet();
        //获取单元格
        $cellA = $sheet -> getCell('A1');
        //设置单元格值
        $cellA -> setValue('囚牛');

//        echo('值: '.$cellA -> getValue());
//
//        echo('坐标: '.$cellA -> getCoordinate());

        //获取单元格
        $cellB = $sheet -> getCellByColumnAndRow(1, 2);
        //设置单元格值
        $cellB -> setValue('睚眦');

        //获取设置单元格,链式操作
        $sheet -> getCell('A3') -> setValue('嘲风');
        $sheet -> getCellByColumnAndRow(1, 4) -> setValue('蒲牢');
        $sheet -> getCell('A5') -> setValue('狻猊');
        $sheet -> getCellByColumnAndRow(1, 6) -> setValue('霸下');
        $sheet -> getCell('A7') -> setValue('狴犴');
        $sheet -> getCellByColumnAndRow(1, 8) -> setValue('负屃');
        $sheet -> getCell('A9') -> setValue('螭吻');

        //定义文件名称,需要带有定义的后缀名
        $filename = 'test.xlsx';
        ob_end_clean(); //清除缓冲区,避免乱码
        //将输出重定向到客户端的web浏览器
        header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
        header('Content-Disposition: attachment;filename="' . $filename . '"');
        header('Cache-Control: max-age=0');
        //如果浏览器为IE9
        header('Cache-Control: max-age=1');
        //如果通过SSL向IE提供服务
        header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
        header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
        header('Cache-Control: cache, must-revalidate');//HTTP/1.1
        header('Pragma: public');//HTTP/1.0
        $writer = IOFactory ::createWriter($spreadsheet, 'Xlsx');
        $writer -> save('php://output');
        exit;
    }
}

Thinkphp5中使用PhpSpreadsheet实现excel的导入导出_第3张图片

3、进阶使用
1.设置单元格的值

setCellValue(‘参数1’,‘参数2’)
参数1:单元格位置
参数2:单元格的值

setCellValueByColumnAndRow(‘参数1’,‘参数2’,‘参数3’)
参数1:列位置
参数2:行位置
参数3:单元格的值

    /**
     * @param Request $request
     * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
     */
    public function downExcel(Request $request)
    {
        //实例化Spreadsheet对象
        $spreadsheet = new Spreadsheet();
        //获取活动工作薄
        $sheet = $spreadsheet -> getActiveSheet();

        //定义一个excel的header表头
        $header = ['A1'=>'ID','B1'=>'昵称','C1'=>'登录名','D1'=>'手机号','E1'=>'邮箱'];
        foreach ($header as $key=>$value) {
            $sheet->setCellValue($key,$value);
        }
        //定义excel之中的内容
        $list_data = [
          [
              'id'=>1,
              'nickname'=>'xiaowang',
              'name'=>'小王',
              'phone'=>12345678900,
              'mail'=>'[email protected]'
          ],
            [
                'id'=>2,
                'nickname'=>'xiaoli',
                'name'=>'小李',
                'phone'=>12345678900,
                'mail'=>'[email protected]'
            ]
        ];

        $i = 2;//excel表格从第2行开始填入数据
        foreach ($list_data as $k => $v) {
            $sheet->setCellValueByColumnAndRow(1,$i,$v['id']);
            $sheet->setCellValueByColumnAndRow(2,$i,$v['nickname']);
            $sheet->setCellValueByColumnAndRow(3,$i,$v['name']);
            $sheet->setCellValueByColumnAndRow(4,$i,$v['phone']);
            $sheet->setCellValueByColumnAndRow(5,$i,$v['mail']);

            $i++;//$i从2累加
        }

        //定义文件名称,需要带有定义的后缀名
        $filename = 'test.xlsx';
        ob_end_clean(); //清除缓冲区,避免乱码
        //将输出重定向到客户端的web浏览器
        header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
        header('Content-Disposition: attachment;filename="' . $filename . '"');
        header('Cache-Control: max-age=0');
        //如果浏览器为IE9
        header('Cache-Control: max-age=1');
        //如果通过SSL向IE提供服务
        header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
        header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
        header('Cache-Control: cache, must-revalidate');//HTTP/1.1
        header('Pragma: public');//HTTP/1.0
        $writer = IOFactory ::createWriter($spreadsheet, 'Xlsx');
        $writer -> save('php://output');
        exit;
    }

Thinkphp5中使用PhpSpreadsheet实现excel的导入导出_第4张图片

2.设置获取单元格的样式

getStyle(‘参数1’) 获取单元格样式
参数1:单元格的位置
getFont() 获取单元格文字样式
setBold(参数1) 设置文字粗细
参数1:true加粗
参数1:false取消
setName(‘参数1’) 设置文字字体
参数1:字体
setSize(参数1) 设置文字大小
参数1:字体大小

        //B1昵称字体加粗,设置成宋体,字号20
        $sheet->getStyle('B1')->getFont()->setBold(true)->setName('宋体')->setSize(20);

Thinkphp5中使用PhpSpreadsheet实现excel的导入导出_第5张图片

getColor() 获取坐标颜色
getRGB() 获取字体颜色
getARGB() 获取字体颜色

setRGB(‘参数1’) 设置字体颜色
参数1:颜色值
setARGB(‘参数1’) 设置字体颜色
参数1:颜色值

        //设置单元格C2字体的颜色为#6F00D2
        $sheet->getStyle('C2')->getFont()->getColor()->setRGB('#6F00D2');
        //设置单元格C3字体的颜色为8F006D
        $sheet->getStyle('C3')->getFont()->getColor()->setARGB('8F006D');
        //也可以使用插件自带的颜色设置
        $sheet->getStyle('C3')->getFont()->getColor()->setARGB(Color::COLOR_YELLOW);

Thinkphp5中使用PhpSpreadsheet实现excel的导入导出_第6张图片

getNumberFormat() 获取格式
setFormatCode(NumberFormat::参数1) 设置格式
参数1:各种不同的表格数字格式,详见方法中的类

        //设置F1单元格的日期格式为yyyy-mm-dd
        $sheet->setCellValue('F1','2020-10-14');
        $sheet->getStyle('F1')->getNumberFormat()->setFormatCode(NumberFormat::FORMAT_DATE_YYYYMMDD2);

Thinkphp5中使用PhpSpreadsheet实现excel的导入导出_第7张图片

setWrapText(参数1) 设置文本里的\n符合为:换行
参数1:true

        //设置单元格中的内容换行
        $sheet->setCellValue('F1',"家庭住址\n详细地址");
        $sheet->getStyle('F1')->getAlignment()->setWrapText(true);

Thinkphp5中使用PhpSpreadsheet实现excel的导入导出_第8张图片

getHyperlink()获取单元格链接
setUrl(‘参数1’)设置单元格链接
参数1:需要添加的链接

        //设置单元格链接
        $sheet->setCellValue('F1','https://www.baidu.com/');
        $sheet->getCell('F1')->getHyperlink()->setUrl('https://www.baidu.com/');

Thinkphp5中使用PhpSpreadsheet实现excel的导入导出_第9张图片
列宽
getColumnDimension(‘参数1’)获取整列
setWidth(参数1)
参数1:像素值
getDefaultColumnDimension()获取默认列宽

        //将A列宽度设置为30
        $sheet->getColumnDimension('A')->setWidth(30);

在这里插入图片描述

        //如果需要自动计算列宽
        $sheet->getColumnDimension('B')->setAutoSize(true);

Thinkphp5中使用PhpSpreadsheet实现excel的导入导出_第10张图片

        //设置默认列宽为12
        $sheet->getDefaultColumnDimension()->setWidth(12);

在这里插入图片描述

行高
getRowDimension(‘参数1’)
参数1:行数
setRowHeight(参数1)
参数1:像素值

        //设置第2行行高为100
        $sheet->getRowDimension('2')->setRowHeight(100);

Thinkphp5中使用PhpSpreadsheet实现excel的导入导出_第11张图片

        //设置默认行高
        $sheet->getDefaultRowDimension()->setRowHeight(15);

applyFromArray(参数1)批量设置单元格样式
参数1:单元格样式数组

        //文字对齐
        $styleArray = [
            'alignment' => [
                //'horizontal' => Alignment::HORIZONTAL_CENTER,//水平居中
                //'vertical' => Alignment::VERTICAL_CENTER,//垂直居中
                'horizontal' => 'center',//水平居中
                'vertical' => 'center',//垂直居中
            ],
        ];
        $sheet->getStyle('B2')->applyFromArray($styleArray);

在这里插入图片描述
合并单元格
mergeCells(‘参数1:参数2’)将指定位置的单元格合并起来
参数1:左上角位置
参数2:右下角位置

        //将A4到B5合并为一个单元格。
        $sheet->mergeCells('A4:B5');

Thinkphp5中使用PhpSpreadsheet实现excel的导入导出_第12张图片
拆分单元格
unmergeCells(‘参数1:参数2’)将指定位置的单元格拆分起来
参数1:左上角位置
参数2:右下角位置

        //合并单元格
        //将A4到B5合并为一个单元格。
        $sheet->mergeCells('A4:B5');

        //拆分单元格
        //将合并后的单元格拆分。
        $sheet->unmergeCells('A4:B5');

Thinkphp5中使用PhpSpreadsheet实现excel的导入导出_第13张图片

        //单元格加边框
        //将B2至B3的区域添加红色边框。
        $styleArray = [
            'borders' => [
                'outline' => [
                    'borderStyle' => Border::BORDER_THICK,
                    'color' => ['argb' => 'FFFF0000'],
                ],
            ],
        ];
        $sheet->getStyle('B2:B3')->applyFromArray($styleArray);

在这里插入图片描述

3.批量填充数据

fromArray(参数1,参数2,参数3) 从数组中的值填充工作表
参数1:数据(数组)
参数2:去除某个值
参数3:从哪个位置开始

        //定义excel之中的内容
        $list_data = [
          [
              'id'=>1,
              'nickname'=>'xiaowang',
              'name'=>'小王',
              'phone'=>12345678900,
              'mail'=>'[email protected]'
          ],
            [
                'id'=>2,
                'nickname'=>'xiaoli',
                'name'=>'小李',
                'phone'=>12345678900,
                'mail'=>'[email protected]'
            ]
        ];
        //从A2行开始填充数据
        $sheet->fromArray($list_data, '', 'A2');
        //        $i = 2;//excel表格从第2行开始填入数据
//        foreach ($list_data as $k => $v) {
//            $sheet->setCellValueByColumnAndRow(1,$i,$v['id']);
//            $sheet->setCellValueByColumnAndRow(2,$i,$v['nickname']);
//            $sheet->setCellValueByColumnAndRow(3,$i,$v['name']);
//            $sheet->setCellValueByColumnAndRow(4,$i,$v['phone']);
//            $sheet->setCellValueByColumnAndRow(5,$i,$v['mail']);
//
//            $i++;//$i从2累加
//        }

在这里插入图片描述

4.设置导出的excel格式
$writer = IOFactory ::createWriter($spreadsheet, 'Xlsx');
$writer = IOFactory ::createWriter($spreadsheet, 'Xls');
5.读取excel中的数据
    /**
     * @throws \PhpOffice\PhpSpreadsheet\Reader\Exception
     */
    public function importExcel()
    {
        //IOFactory来判断获取的文件格式
        $reader = IOFactory ::createReader('Xlsx');

        //当只要读取数据,不要格式时,实例读取器中 readDataOnly 属性
        $reader -> setReadDataOnly(true);
        $spreadsheet = $reader -> load('C:\Users\admin\Desktop\demo.xlsx');

        $worksheet = $spreadsheet -> getActiveSheet();
        //总行数
        $row = $worksheet -> getHighestRow();
        //总列数
//        $column = $worksheet -> getHighestColumn();

        $insert_data = $temp = [];
        for ($rowIndex = 2; $rowIndex <= $row; $rowIndex++) {
            //getCellByColumnAndRow中的第一参数为列的A,B,C,用1,2,3代替,第二参数为行号
            $temp['num'] = $worksheet -> getCellByColumnAndRow(1, $rowIndex) -> getValue();
            $temp['name'] = $worksheet -> getCellByColumnAndRow(2, $rowIndex) -> getValue();
            $temp['code'] = $worksheet -> getCellByColumnAndRow(3, $rowIndex) -> getValue();
            $temp['page'] = $worksheet -> getCellByColumnAndRow(4, $rowIndex) -> getValue();
            $temp['type'] = $worksheet -> getCellByColumnAndRow(5, $rowIndex) -> getValue();
            $temp['province'] = $worksheet -> getCellByColumnAndRow(6, $rowIndex) -> getValue();
            $temp['city'] = $worksheet -> getCellByColumnAndRow(7, $rowIndex) -> getValue();
            $temp['town'] = $worksheet -> getCellByColumnAndRow(8, $rowIndex) -> getValue();
            $temp['class'] = $worksheet -> getCellByColumnAndRow(9, $rowIndex) -> getValue();
            $temp['design'] = $worksheet -> getCellByColumnAndRow(10, $rowIndex) -> getValue();
            $temp['complete_time'] = $worksheet -> getCellByColumnAndRow(11, $rowIndex) -> getValue();
            $temp['remark'] = $worksheet -> getCellByColumnAndRow(12, $rowIndex) -> getValue();

            $insert_data[] = $temp;
        }
        //生成的$insert_data可以导入数据库中
    }
4、总结

使用 PhpSpreadsheet 操作 excel 确实方便了很多,还有很多的其他的功能属性有待后续的学习。

你可能感兴趣的:(thinkphp,excel,thinkphp)