Laravel 插件 PhpSpreadSheet 使用总结

背景说明

最近在做一个 Laravel 的项目,其中需要将 Excel 表格录入数据库进行下一步处理。在查阅了一些资料之后,决定使用 PhpSpreadSheet 插件来完成这个功能。PhpSpreadSheet 是 PhpExcel (已被弃用)的升级版,据说功能更加强大。PhpSpreadSheet 的教程没有 PhpExcel 多,可能是因为比较新的原因。在查阅了很多资料之后,找到了一个比较适合自己的教程:使用PhpSpreadsheet读取和写入Excel。结合PhpSpreadSheet 官方文档,初步学会了如何在 Laravel 项目中使用 PhpSpreadSheet。下面是对自学 PhpSpreadSheet 的一些总结。

自学笔记

前期准备

  • 安装 PhpSpreadSheet:
    这个可以参考背景说明中提到的教程,或者官方文档,讲的很详细。
  • 首先将需要读取的表格上传到本地磁盘:
    /config/filesystems.php 中的 disks=>[ ... ] 添加一段储存路径:
        'uploads' => [
            'driver' => 'local',
            'root' => public_path('uploads/'.date('Ymd')), // 这是上传的文件所储存的路径
        ],

    并在 public 文件夹内新建一个 uploads 文件夹。以后上传的文件都会放在这个文件夹里。
    (如果无需储存,这一步可以忽略)

  • 新建一个 Controller:
    > php artisan make:controller TestsController

    并写一个 index 方法来获取视图:
    App\Http\Controllers\TestsController.php

    <?php
    namespace App\Http\Controllers;
    use Illuminate\Http\Request;
    use App\Test;
    public function index()
    {
    return view('tests.index');
    }
  • 在相应的文件夹新建一个简单的视图上传文件:
    resources/views/tests/index.blade.php
    <!-- 显示上传文件产生的错误 -->
    @if (count($errors) > 0)
    <div class="alert alert-danger">
    <ul>
      @foreach($errors->all() as $error)
        <li>{{ $error }}</li>
      @endforeach
    </ul>
    </div>
    @endif
    <!--  表格视图 -->
    <form class="form-inline definewidth m20" method="POST" action="{{ route('tests.import') }}" enctype="multipart/form-data">
    {{ csrf_field() }}
    选择表格
    <input id="file" type="file" class="form-control" name="select_file" accept="">
    <button type="submit" class="btn btn-success">上传表格</button>
    </form>
  • 建立相应的路径:
    routes/web.php
    <? php
    .
    .
    .
    Route::resource('/tests','TestsController');
    Route::post('/tests/import','TestsController@import')->name('tests.import');

正式开始使用 PhpSpreadSheet

  • 在TestsController 里写一个 import 方法:
    App\Http\Controllers\TestsController.php
    <?php
    namespace App\Http\Controllers;
    use Illuminate\Http\Request;
    use App\Attendance;
    use Illuminate\Support\Facades\Storage;
    use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
    use PhpOffice\PhpSpreadsheet\Reader\Xls;
    use PhpOffice\PhpSpreadsheet\IOFactory;
    use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
    .
    .
    .
    public function import(Request $request)
    {
    // 要求上传的文件类型必须是表格格式
     $this->validate($request, [
      'select_file'  => 'required|mimes:xls,xlsx'
     ]);
    // 如果是 POST 方法才读取文件
    if ($request->isMethod('POST')){
        $file = $request->file('select_file');
        // 判断文件是否上传成功
        if ($file->isValid()){
            // 原文件名
            $originalName = $file->getClientOriginalName();
            // 临时绝对路径
            $realPath = $file->getRealPath();
            // 修改文件名
            $filename = date('Y-m-d-h-i-s').'-'.$originalName;
            // 储存到磁盘相应的路径
            $bool = Storage::disk('uploads')->put($filename,file_get_contents($realPath));
            //判断是否上传成功
            if($bool){
                $path = public_path('uploads/'.date('Ymd')).'/'.$filename;
                $reader = new Xlsx();
                // $reader = new Xls();
                $reader->setReadDataOnly(TRUE);
                $spreadsheet = $reader->load($path); 
                // 至此导入表格成功,我们可以运用 PhpSpreadSheet 所提供的方法来获取表格的数据,存入数据库
                // 一个例子:
                $worksheet = $spreadsheet->getActiveSheet();  // 获取当前的工作表数据
                // dump($spreadsheet);
                // dump($worksheet);
                .
                .
                .
            }else{
                session()->flash('danger','文件上传失败!');
                return redirect()->back();
            }
        }
    }
    }

    说明:如果无需储存表格,就可以不调用 Storage 方法,利用 PhpSpreadSheet 读取表格时,直接获取上传表格得到的临时路径即可:$spreadsheet = $reader->load($realPath)

成功导入表格后,我们可以使用 dump() 来查看一下导入数据的参数,结果如图:
dump($spreadsheet)

Laravel 插件 PhpSpreadSheet 使用总结
dump($worksheet)

Laravel 插件 PhpSpreadSheet 使用总结

我用到的 PhpSpreadSheet 方法 (持续更新)

导入工作表相关操作:

  • 获取工作簿中工作表的总数
    $num = $spreadsheet->getSheetCount();
  • 读取当前工作表
    $worksheet = $spreadsheet->getActiveSheet();  // 获取当前的工作表数据
  • 根据工作表的索引读取工作表
    $worksheet = $spreadsheet->getSheet($index);
  • 读取一张工作表的总行数
    $highestRow = $worksheet->getHighestRow();
  • 读取一张工作表的总列数
    $highestColumn = $worksheet->getHighestColumn();
  • 获取最后一列的索引
    $highestColumnIndex = Coordinate::columnIndexFromString($highestColumn);
  • 获取某一单元格的值
    这是获取数据录入数据库的关键一步!
    $value = $worksheet->getCellByColumnAndRow($column,$row)->getValue();

    导出工作表相关操作:

    我们都需要新建对象进行后续操作:

    $spreadsheet = new Spreadsheet();
    $worksheet = $spreadsheet->getActiveSheet();
  • 设置工作表标题
    $worksheet->setTitle('工作表标题');
  • 给某一单元格赋值
    $worksheet->setCellValueByColumnAndRow(1, 1, '测试');
  • 合并单元格
    $worksheet->mergeCells('A1:E1');

样式设置

  • 设置单元格自动换行
    $worksheet->getStyle('A1')->getAlignment()->setWrapText(true);
  • 设置列宽
    $worksheet->getColumnDimension('C')->setWidth(10); // 某一列列宽设置为10
    $worksheet->getColumnDimension('C')->setAutoSize(true); // 自动调整列宽
    $worksheet->getDefaultColumnDimension()->setWidth(12); // 默认列宽设置为12
  • 设置行高
    
    $worksheet->getRowDimension('10')->setRowHeight(100);
    $worksheet->getDefaultRowDimension()->setRowHeight(15); // 设置默认行高
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 3

写得很详细,感谢大佬

1个月前 评论
Borris (楼主) 1个月前
yangweijie

有没有函数和autofilter相关的文档,政务的一个订单报表搞好久无法动态生成,导入就报错

1个月前 评论
Borris (楼主) 1个月前
Borris (楼主) 1个月前

非常感谢,萌新英语又不好,幸亏看到了这边文档

4周前 评论

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!