こちらはJoolen Advent Calendar 2019 2日目の記事です。
前日の記事は@motuoさんのEC-CUBE4系(Symfony)のtwigをAjax( jQuery)を使ってValidationしてみた。でした。
カレンダーのURLはこちら
Joolen Advent Calendar 2019
まえがき
最近PHPを使用して、xlsxファイルをPDFに変換する業務がありました。
色々試した結果LibreOfficeに落ち着きました。
その理由を実際に変換した結果とともに書きます。
環境
- macOS Mojave
- PHP7.2
- Composer 1.9.1
PDFへの変換方法の選択肢
そもそもPHPでxlsxをPDFに変換できるのか?
そんな疑問から色々ネットの海を泳いだ結果、以下の情報を得ました。
- PhpSpreadsheetとDompdfなどを利用して変換する
- LibreOfficeをインストールして、PHPからコマンドを呼び出す
とりあえずやってみよう!
1. PhpSpreadsheetとDompdfなどを利用して変換する
まずはPHPでExcelをファイルを弄れることで有名なPhpSpreadsheetを使用してみます。
PhpSpreadsheetはDompdfの他にmPDFとTCPDFが対応しているので、全て試します。
必要なライブラリをインストール
作業ディレクトリはこんな感じです。
.
├── composer.json
├── composer.lock
├── src
└── storage
├── excel
└── pdf
composerで各種ライブラリインストール
$ composer require phpoffice/phpspreadsheet
$ composer require dompdf/dompdf
$ composer require mpdf/mpdf
$ composer require tecnickcom/tcpdf
composer.jsonを確認
{
(中略)
"require": {
"phpoffice/phpspreadsheet": "^1.9",
"dompdf/dompdf": "^0.8.3",
"mpdf/mpdf": "^8.0"
"tecnickcom/tcpdf": "^6.3",
}
}
OK!!
サンプルエクセルファイル作成
私の手元のPCにはエクセルが入ってないので、Google スプレッドシートで以下の納品書のようなものを作成
このファイルをstorage/excel
の中に保存します。
.
├── composer.json
├── composer.lock
├── src
└── storage
├── excel
│ └── delivery-note.xlsx <- 作成したエクセルファイル
└── pdf
コードを書く
<?php
require __DIR__ . '/../vendor/autoload.php';
use PhpOffice\PhpSpreadsheet\IOFactory;
$orderNote = __DIR__ . '/../storage/excel/order-note.xlsx';
echo "load: $orderNote", PHP_EOL;
$reader = IOFactory::createReader('Xlsx');
$spreadsheet = $reader->load($orderNote);
// Dompdfを使用してエクスポート
outputPdf($spreadsheet, 'Dompdf');
// mPDFを使用してエクスポート
outputPdf($spreadsheet, 'Mpdf');
// TCPDFを使用してエクスポート
outputPdf($spreadsheet, 'Tcpdf');
function outputPdf($spreadsheet, $writerType) {
$writer = IOFactory::createWriter($spreadsheet, ucfirst(strtolower($writerType)));
$writer->save(__DIR__ . '/../storage/pdf/' . strtolower($writerType) . '.pdf');
}
実行した結果PDFファイルが追加されました。
中身を見てみましょう。
Dompdf
mPDF
TCPDF
TCPDFの驚きの白さ。
DompdfとmPDFは文字化けと印刷設定でなんとかなるかもしれないですね。罫線が一部消えてるのが気になりますが。。。
この後文字化け対策でフォント入れようとしたのですが、上手く出来ませんでした。
知っている方いれば教えてください。。。
2. LibreOfficeをインストールして、PHPからコマンドを呼び出す
LibreOfficeは無料で使えるオフィスソフトです。
コマンドラインからも色々な操作ができるので、それを利用してxlsxをPDFに変換します。
LibreOfficeのインストール
下記のURLからインストールします。
https://ja.libreoffice.org/download/download/
Linuxの場合はyumやapt-getにあると思います。
コードを書く
先ほど書いたコードにLibreOfficeを使用して変換する処理を追加します.
<?php
require __DIR__ . '/../vendor/autoload.php';
use PhpOffice\PhpSpreadsheet\IOFactory;
$orderNote = __DIR__ . '/../storage/excel/order-note.xlsx';
echo "load: $orderNote", PHP_EOL;
(中略)
// LibreOfficeを使用してエクスポート
$soffice = '/Applications/LibreOffice.app/Contents/MacOS/soffice';
$command = "$soffice --headless --convert-to pdf --outdir " . __DIR__ . "/../storage/pdf $orderNote";
echo $command, PHP_EOL;
exec($command);
悪くないですが、高さの自動調整が効いてないですね。
LibreOfficeはシステムフォントを利用するようなので、Linuxでも日本語化は苦ではない。
PhpSpreadsheetとLibreOfficeを使用してPDF変換した結果は以上です。
まとめ
- LibreOfficeは高さの自動調整だけ気をつければ大丈夫そう
- 日本語化できるならPhpSpreadsheetも使えるかも
- そもそもPHPでxlsxをPDFに変換するのは向いてない
- どうしてもやるならLibreOfficeが一番楽で綺麗
以上です。
明日は@hwatryさんのTS初心者がハマった初歩の初歩です。