[PhpSpreadsheet]バイナリデータから画像を出力する

要点だけ。

全体の理解

どんな感じで画像情報を取り出して、どんな感じで放り込むかを理解しないと詰む。

通常の画像挿入はDrawingだけど、バイナリから引っ張る場合はMemoryDrawingを使うことになる。

MemoryDrawingはbase64を使う。

base64はこういうやつ。

画像やPDFをBase64エンコード(変換)してHTMLに埋め込んでサイトの表示速度を速くする | Free Style
Googleの検索エンジンでWebページの表示速度が速いと、ユーザーにストレスを与えないので検索順位が上がるなどいろいろ言われている中で、表示速度を速くする方法の1つとしてHTTPリクエストを減らすという方法があります。今回は、画像やPDF...

色々WEBサイトを見てると偶に見かけるやつ。

やっていく

こんな感じで格納してたとする。

<?php
//データベースから情報を取る
$id = $_GET['id'];
$pdo = new PDO( 'mysql:host=***;dbname=***;', '***', '***', [ PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC ]);
$stmt = $pdo->prepare("SELECT * FROM *** WHERE id IN ($id)");
$stmt->execute();
$row = $stmt->fetch();

//PHPSpreadsheetをやっていく
require 'vendor/autoload.php';
use PhpOffice\PhpSpreadsheet\Spreadsheet;
︙
use PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing; //忘れずに読み込ませる
$spreadsheet = new Spreadsheet();

//画像の情報を拾ってPHPSpreadsheetに放り込む
if(!empty($row['image1'])){
    $imageBLOB = $row['image1'];
    $imageMIME = $row['image1_genre'];
    $img = base64_encode($imageBLOB);
    $image_url = 'data:'.$imageMIME.';base64,'.$img;
    if($imageMIME == 'image/jpeg'){$rendering = MemoryDrawing::RENDERING_JPEG;}
    else if($imageMIME == 'image/gif'){$rendering = MemoryDrawing::RENDERING_GIF;}
    else if($imageMIME == 'image/png'){$rendering = MemoryDrawing::RENDERING_PNG;}
    else{$rendering == MemoryDrawing::RENDERING_DEFAULT;}
    if($imageMIME == 'image/jpeg'){$mimetype = MemoryDrawing::MIMETYPE_JPEG;}
    else if($imageMIME == 'image/gif'){$mimetype = MemoryDrawing::MIMETYPE_GIF;}
    else if($imageMIME == 'image/png'){$mimetype = MemoryDrawing::MIMETYPE_PNG;}
    else{$mimetype == MemoryDrawing::MIMETYPE_DEFAULT;}
    $data = base64_decode(explode(',', $image_url)[1]);

    $drawing = new MemoryDrawing();
    $drawing->setImageResource(imagecreatefromstring($data));
    $drawing->setRenderingFunction($rendering);
    $drawing->setMimeType($mimetype);
    $drawing->setCoordinates('A1');
    $drawing->getShadow()->setVisible(true);
    $drawing->setHeight(320);
    $drawing->setWorksheet($spreadsheet->getActiveSheet());
}

//書き出し
$writer = new Xlsx($spreadsheet);
$writer->save('export/excel.xls');

ファイル形式により設定しなきゃいけない項目があるので注意。

対応形式はJPG、GIF、PNGみたい。まあこれから外れることはあんまりないだろうけど。WebPとかSVGはどうなるんでしょうね。

Documentation

MemoryDrawingはbase64からやっていくのだけど、BLOBはそのままだとbase64じゃないので一旦base64にエンコードして、更にデコードして、必要な情報を突っ込むことになる。

頑張りましょう。

コメント

タイトルとURLをコピーしました