こんにちは。株式会社リンクネット、ソリューション事業部の高橋です。
前回の記事PHPでエクセルファイルを作成し、PDFとして出力する。(1)では
Dockerコンテナを起動する度に、sail root-shellでのlibreofficeや日本語フォントのインストールが必要な事が課題として残っておりました。
本記事では、Dockerfileをカスタマイズし、毎回の手動インストールを省略できるようにする方法を共有します。
$ sail artisan -V
Laravel Framework 8.82.0
$ sail php -v
PHP 8.1.5 (cli) (built: Apr 21 2022 10:15:06) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.1.5, Copyright (c) Zend Technologies
with Zend OPcache v8.1.5, Copyright (c), by Zend Technologies
with Xdebug v3.1.2, Copyright (c) 2002-2021, by Derick Rethans
Dockerコンテナをカスタマイズする際に下記のコマンドを実行します。
Dockerfileをカスタマイズできるようにプロジェクトの管理化に移動します。
sail artisan sail:publish
コマンドを実行すると下記のようにdockerディレクトリが生成されます。
+ drwxr-xr-x 6 appuser appuser 4096 Nov 22 10:25 docker/
docker-compose.ymlにも下記のように変更されます。
変更内容はDockerfileの参照先が変更されています。
- context: ./vendor/laravel/sail/runtimes/8.1
+ context: ./docker/8.1
/home/appuser/project/portal-backend/docker
|--7.4
| |--Dockerfile
| |--php.ini
| |--start-container
| |--supervisord.conf
|--8.0
| |--Dockerfile
| |--php.ini
| |--start-container
| |--supervisord.conf
|--8.1
| |--Dockerfile
| |--php.ini
| |--start-container
| |--supervisord.conf
|--8.2
|--Dockerfile
|--php.ini
|--start-container
|--supervisord.conf
今回、必要なコンテナは8.1のためdocker-compose.yml参照先の変更、
docker ディレクトリ直下に8.1のファイルを移動します。
- context: ./docker/8.1
+ context: ./docker/
./docker
- |--7.4
- | |--Dockerfile
- | |--php.ini
- | |--start-container
- | |--supervisord.conf
- |--8.0
- | |--Dockerfile
- | |--php.ini
- | |--start-container
- | |--supervisord.conf
- |--8.1
- | |--Dockerfile
- | |--php.ini
- | |--start-container
- | |--supervisord.conf
- |--8.2
- |--Dockerfile
- |--php.ini
- |--start-container
- |--supervisord.conf
+ Dockerfile
+ php.ini
+ start-container
+ supervisord.conf
今回のカスタマイズの目的はsail root-shellで下記のコマンドを手動実行していたインストール作業を
Dockerコンテナ構築時に自動でインストールするようにカスタマイズします。
apt -y install libreoffice libreoffice-l10n-ja libreoffice-dmaths libreoffice-ogltrans libreoffice-writer2xhtml libreoffice-pdfimport libreoffice-help-ja
apt install fonts-ipafont fonts-ipaexfont
fc-cache -fv
上記のコマンドを設定するためDockerfileに下記の内容を追加しました。
+ && apt -y install libreoffice \
+ libreoffice-l10n-ja \
+ libreoffice-dmaths \
+ libreoffice-ogltrans \
+ libreoffice-writer2xhtml \
+ libreoffice-pdfimport \
+ libreoffice-help-ja \
+ && apt install fonts-ipafont fonts-ipaexfont \
+ && fc-cache -fv \
Dockerコンテナを再構築するため下記のコマンドを実行
$sail build --no-cache
WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
E: Unable to locate package
ERROR: Service 'laravel.test' failed to build: The command
エラー内容を調査してみるとapt
コマンドはCLI向けではないためapt-get
コマンドでないとエラーが出るようです。
下記のようにDockerfileを修正し、Dockerコンテナを再構築してみます。
- && apt -y install libreoffice \
+ && apt-get -y install libreoffice \
+ libreoffice-l10n-ja \
+ libreoffice-dmaths \
+ libreoffice-ogltrans \
+ libreoffice-writer2xhtml \
+ libreoffice-pdfimport \
+ libreoffice-help-ja \
- && apt install fonts-ipafont fonts-ipaexfont \
+ && apt-get install fonts-ipafont fonts-ipaexfont \
+ && fc-cache -fv \
警告のWARNINGは消えましたが、エラーについては発生したままです。
E: Unable to locate package
ERROR: Service 'laravel.test' failed to build: The command
確認しましたところ日本語フォント(IPAフォント)のインストール時に
応答が必要なようですので下記のように-y
オプションを追加しDockerコンテナを再構築します。
+ && apt-get -y install libreoffice \
+ libreoffice-l10n-ja \
+ libreoffice-dmaths \
+ libreoffice-ogltrans \
+ libreoffice-writer2xhtml \
+ libreoffice-pdfimport \
+ libreoffice-help-ja \
- && apt-get install fonts-ipafont fonts-ipaexfont \
+ && apt-get -y install fonts-ipafont fonts-ipaexfont \
+ && fc-cache -fv \
エラーがなくDockerコンテナの再構築は完了しましたので、
libreofficeがインストールされたかsail root-sehll
でコンテナに接続し、
/usr/bin/soffice
へのPATHが存在するかで確認します。
$sail root-sehll
root@834dad2d51be:/var/www/html# cd /usr/bin/
root@834dad2d51be:/usr/bin# pwd
/usr/bin
root@834dad2d51be:/usr/bin# ll | grep soffice
lrwxrwxrwx 1 root root 34 Oct 27 10:34 libreoffice -> ../lib/libreoffice/program/soffice*
lrwxrwxrwx 1 root root 34 Oct 27 10:34 soffice -> ../lib/libreoffice/program/soffice*
libreofficeは問題なくインストールされているようです。
続けて日本語フォント(IPAフォント)が登録されているかも併せて確認します。
fc-match :lang=ja
でデフォルトのフォントを確認します。
root@834dad2d51be:/var/www/html#
root@834dad2d51be:/var/www/html# fc-match :lang=ja
fonts-japanese-gothic.ttf: "IPAexGothic" "Regular"
日本語フォント(IPAフォント)も問題なく登録できているようです。
次にlibreofficeを使用してエクセルファイルをPDFに変換します。
/usr/bin/soffice --headless --convert-to pdf --outdir /var/www/html/storage/app/sample /var/www/html/public/common/sample/sample.xlsx
convert /var/www/html/public/common/sample/sample.xlsx -> /var/www/html/storage/app/sample/sample.pdf using filter : calc_pdf_Export
変換前と変換後の画像はそれぞれ下記となります。
変換自体は正常に終了し日本語フォントは文字化けせずに表示されています。
今回はPhpSpreadsheet
で印刷範囲をしていないため、変換後のPDFは2ページになりました。
・変換前のエクセルファイル
・変換後のPDFファイル
前回と同様にPhpSpreadsheet
を用いてPHPでエクセルファイルをPDFに変換します。
変換に使用したPHPのソースコードの抜粋と変換後のPDFは下記となります。
$this -> info('export start');
$tmp_path = storage_path('app/sample');
if(!file_exists($tmp_path)){
mkdir($tmp_path, 0777, true);
}
$format = public_path('common/sample/sample.xlsx');
$tmp_xlsx_path = $tmp_path.'/tmp.xlsx';
$tmp_pdf_path = $tmp_path.'/sample.pdf';
$xr = new XReader();
$xr -> setReadDataOnly(false); //これをfalseにしないと複写できない
$spread = $xr -> load($format);
$sheet = $spread -> getActivesheet();
$sheet -> getPageSetup() -> setPrintArea('A1:AR46');
$sheet -> getPageSetup() -> setScale(90);
$sheet -> getPageSetup() -> setPaperSize(PageSetup::PAPERSIZE_A4); //A4サイズ
//xlsxファイルを出力
$writer = new XlsxWriter($spread);
$writer -> save($tmp_xlsx_path);
$command = '/usr/bin/soffice --headless --convert-to pdf --outdir '.$tmp_path.' '.$tmp_xlsx_path;
if(exec($command)){
unlink($tmp_xlsx_path);
}
return Command::SUCCESS;
・変換後のPDFファイル
今回は、PDF変換のために必要なlibreofficeや日本語フォントをDockerコンテナ構築時にインストールさせる方法をまとめました。
今後、Dockerコンテナに別のフォントやアプリケーションが必要になった際、
本記事と同様の手法を用いることで様々な案件で応用が可能です。