最近在做一個 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)
dump($worksheet)
我用到的 PhpSpreadSheet 方法 (持續更新)
$num = $spreadsheet->getSheetCount(); // Worksheet 的總數
$worksheet = $spreadsheet->getSheet(0); // 根據 index 讀取指定的 worksheet
$highestRow = $worksheet->getHighestRow(); // 總行數
$highestColumn = $worksheet->getHighestColumn(); // 總列數
$highestColumnIndex = Coordinate::columnIndexFromString($highestColumn);