18
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

JoolenAdvent Calendar 2019

Day 2

PHPでxlsxファイルをPDFに変換するならLibreOfficeしかないな

Last updated at Posted at 2019-12-01

こちらは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に変換できるのか?
そんな疑問から色々ネットの海を泳いだ結果、以下の情報を得ました。

  1. PhpSpreadsheetとDompdfなどを利用して変換する
  2. 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を確認

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

コードを書く:computer:

src/xlsx-to-pdf.php
<?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

:thinking: :thinking: :thinking:

TCPDFの驚きの白さ。
DompdfとmPDFは文字化けと印刷設定でなんとかなるかもしれないですね。罫線が一部消えてるのが気になりますが。。。
この後文字化け対策でフォント入れようとしたのですが、上手く出来ませんでした。
知っている方いれば教えてください。。。

2. LibreOfficeをインストールして、PHPからコマンドを呼び出す

LibreOfficeは無料で使えるオフィスソフトです。
コマンドラインからも色々な操作ができるので、それを利用してxlsxをPDFに変換します。

LibreOfficeのインストール

下記のURLからインストールします。
https://ja.libreoffice.org/download/download/

Linuxの場合はyumやapt-getにあると思います。

コードを書く:computer:

先ほど書いたコードにLibreOfficeを使用して変換する処理を追加します.

src/xlsx-to-pdf.php
<?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初心者がハマった初歩の初歩です。

18
18
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?