Laravel 外掛 PhpSpreadSheet 使用總結

Borris發表於2019-06-10

最近在做一個 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();
            }
        }
    }
    }

    成功匯入表格後,我們可以使用 dump() 來檢視一下匯入資料的引數,結果如圖:
    dump($spreadsheet)

Laravel 外掛 PhpSpreadSheet 使用總結
dump($worksheet)

Laravel 外掛 PhpSpreadSheet 使用總結

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

$num = $spreadsheet->getSheetCount(); // Worksheet 的總數
$worksheet = $spreadsheet->getSheet(0); // 根據 index 讀取指定的 worksheet
$highestRow = $worksheet->getHighestRow(); // 總行數
$highestColumn = $worksheet->getHighestColumn(); // 總列數
$highestColumnIndex = Coordinate::columnIndexFromString($highestColumn);

相關文章