PhpSpreadsheetでテキストファイル(csv,txt)読み込み


とても簡単だし公式ドキュメントみたらわかるけど自分の備忘録として。
そして超初心者向けです。間違いがあるかもなのでご指摘ください。

環境

  • php 7.1.4
  • Phpspreadsheet 1.1.0
  • Laravel Framework 5.5.34

version確認のコマンドってなんだっけ・・・?ってよくなるので書いとこ

  • php php -v
  • Phpspreadsheet composer show
  • laravel php artisan --version

テキストファイルの読み込み

用意したのはメモ帳のテキストファイル。

読みこむファイルタイプがテキストファイルとわかっているのでcsvタイプのreaderオブジェクトをインスタンス化してファイルをspreadsheetオブジェクトに読み込みます。

Controller
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Csv();
$spreadsheet = $reader->load($filePath);

わたしはviewからファイルを送ってたのでファイルパスは以下のような形で受け取ってる

Controller
$filePath = request()->file('fileName');

読み込みオプション

ファイル形式に注意

Note that \PhpOffice\PhpSpreadsheet\Reader\Csv by default assumes that the loaded CSV file is UTF-8 encoded.
(デフォルトで\ PhpOffice \ PhpSpreadsheet \ Reader \ Csvは、ロードされたCSVファイルがUTF-8でエンコードされていることを前提としています。)

読み込みテキストファイルが’SJIS’なんだけど!というときはインスタンス化した後に

Controller
$reader->setInputEncoding('SJIS');

とすると文字もちゃんと読んでくれます。

その他もろもろ設定可能。詳しくは公式ドキュメントを見て。

データの格納

で、読み込んだシートからデータをいい感じに格納する

Controller
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;

$sheet = $spreadsheet->getSheet(0);

// rowとcolのデータ領域を確認
$rowMax = $sheet->getHighestRow();  
$colMaxStr = $sheet->getHighestColumn();
$colMax = Coordinate::columnIndexFromString($colMaxStr);

// 1セルごとにテキストデータを取得
$sheetData = [ ];
for($r = 1; $r <= $rowMax; $r ++) {
  for($c = 1; $c <= $colMax; $c ++) {
    $cell = $sheet->getCellByColumnAndRow($c, $r);
    $sheetData[$r][$c] = $cell->getValue();
  }
}

もうわたしはこの方法でしかデータ格納の仕方わかんなかったので他にいい方法があれば教えてください。

(追記)こんなややこしい方法しなくても1行で配列にする方法あった。

Controller

$sheetData = $spreadsheet->getActiveSheet()->toArray();

出力される配列はfor文まわす方法と同じです。断然こっちの方が楽!!!!!
toArrayメソッドの引数は全部で4つ、ほぼデフォでいいと思います。

Worksheet.php
/**
  * Create array from worksheet.
  * @param mixed $nullValue セルが存在しない場合、配列エントリに返される値
  * @param bool $calculateFormulas 数式を計算すべきか?
  * @param bool $formatData Should セル値に書式を適用する必要があるか?
  * @param bool $returnCellRef False - 0から数えてカウントされる行と列の単純な配列を返します
  *                            True - 実際の行IDと列IDによってインデックスされた行と列を返します
  *
  * @return array
  */
 public function toArray($nullValue = null, $calculateFormulas = true, $formatData = true, $returnCellRef = false)
    {
        // Garbage collect...
        $this->garbageCollect();

        //    Identify the range that we need to extract from the worksheet
        $maxCol = $this->getHighestColumn();
        $maxRow = $this->getHighestRow();

        // Return
        return $this->rangeToArray('A1:' . $maxCol . $maxRow, $nullValue, $calculateFormulas, $formatData, $returnCellRef);
    }

$sheetDataの中身は

dump
array:10 [
  1 => array:7 [
    1 => "FF"
    2 => "1987年"
    3 => "FC"
    4 => "wol"
    5 => "カオス"
    6 => "とくれせんたぼーび"
    7 => null
  ]
  2 => array:7 [
    1 => "FF2"
    2 => "1988年"
    3 => "FC"
    4 => "フリオニール"
    5 => "パラメキア帝国初代皇帝"
    6 => "……ゴクッ……"
    7 => null
  ]
  3 => array:7 [
    1 => "FF3"
    2 => "1990年"
    3 => "FC"
    4 => "オニオンナイトorルーネス"
    5 => "暗闇の雲"
    6 => "ファファファ…"
    7 => null
  ]
  4 => array:7 [
    1 => "FF4"
    2 => "1991年"
    3 => "SF"
    4 => "セシル"
    5 => "ゼロムス"
    6 => "いいですとも!"
    7 => null
  ]
  5 => array:7 [
    1 => "FF5"
    2 => "1992年"
    3 => "SF"
    4 => "バッツ"
    5 => "ネオエクスデス"
    6 => "ボコ、行ってくる!"
    7 => null
  ]
  6 => array:7 [
    1 => "FF6"
    2 => "1994年"
    3 => "SF"
    4 => "ティナ"
    5 => "ケフカ"
    6 => "命、夢、希望、どこから来て どこへ行く?そんなものは、この私がハカイする!"
    7 => null
  ]
  7 => array:7 [
    1 => "FF7"
    2 => "1997年"
    3 => "PS"
    4 => "クラウド"
    5 => "セフィロス"
    6 => "興味ないね"
    7 => null
  ]
  8 => array:7 [
    1 => "FF8"
    2 => "1999年"
    3 => "PS"
    4 => "スコール"
    5 => "アルティミシア"
    6 => "壁にでも話してろよ"
    7 => null
  ]
  9 => array:7 [
    1 => "FF9"
    2 => "2000年"
    3 => "PS"
    4 => "ジタン"
    5 => "ペプシマン"
    6 => "誰かを助けるのに理由がいるかい?"
    7 => null
  ]
  10 => array:7 [
    1 => "FF7"
    2 => "2001年"
    3 => "PS2"
    4 => "ティーダ"
    5 => "シン"
    6 => "泣くぞ。すぐ泣くぞ。絶対泣くぞ。ほら泣くぞ。"
    7 => null
  ]
]

なんで最後にnullが入るのかは調査中です。

こんな感じで読み込みができたのであとはこいつをDB保存するなり煮るなり焼くなりご自由に。