ヤッチーのブログ

PHP,Bootstrap,J Query,Swiftやサーバ管理、トラウトのルアー釣り、ハードロック等の記録です

PHP spreadseet

PHPでエクセルの出力には、PHP EXCELを使用していますが、非推奨となり、

PHPversion7.2.* 以降は使えなくなります。

クライアントからのWEBからエクセルに出力したいという昔からよくある依頼には、今後も答え続けなければなりませんので、後継のspreadsheetのお勉強です。

今回の記事は完全な私の備忘録です。画像無いと素っ気ないので、画像載せます。

f:id:php-7com:20190918043346j:plain

f:id:php-7com:20190918043403j:plain


### Xserver SSHの接続の準備 ###
SSH設定 ONにする
公開鍵認証用鍵ペアの生成 パスワード入れて 生成した
example.key ファイルがダウンロードされる。大事に保存する。
公開鍵登録更新「登録済公開鍵を表示」クリックして、「確認画面へ進む」クリックする
公開鍵の登録を完了しました。

### SSHソフトの設定 ###
Tera Term teraterm-4.104.exeダウンロード

Tera Term 設定(S) SSH認証(A)
Authentication methods内
RSA/DSA/ECDSA/ED25519鍵を使う
秘密鍵ファイル(ダウンロードした)を選択し、example.key ファイルを選択し「OK」特に反応ない

ファイルから 新しい接続 ホスト example.xsrv.jp
ヒストリチェック入れたまま TCPポート 10022
SSH SSH2 プロトコル UNSPEC 「OK」
SSH認証「ユーザー名」サーバーID、パスフレーズ秘密鍵パスフレーズ
RSA/DSA/ECDSA/ED25519鍵を使う
秘密鍵example.keyが選択されているのを確認して接続できた!

### 以下 SSHソフト上での操作 ###
Xserverは コントールパネルからは、PHP バージョンが7.2.17であるのに、
SSHで接続するとなぜかバージョン 5.6.*でした。

[example@sv9999 ~]$ ls /opt/
php-5.4.16 php-5.6.18 php-7.0 php-7.0.33 php-7.1.28 php-7.2.17
7.2.17があることを確認

[example@sv9999 ~]$ mkdir $HOME/bin
[example@sv9999 ~]$ ln -s /opt/php-7.2.17/bin/php $HOME/bin/php
[example@sv9999 ~]$ vi ~/.bash_profile

# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
# User specific environment and startup programs
PATH=$HOME/bin:$PATH
export PATH
# User specific aliases and functions

export $HOME/bin:$PATH /*末尾に追加した*/

[example@sv9999 ~]$ source ~/.bash_profile
[example@sv9999 ~]$ php -v

うまくいきません。
しかし、SSH繋ぎなおしたら、なぜか PHP 最新バージョンに変更されていました!

[example@sv9999 ~]$ php -v
PHP 7.2.17 (cli) (built: Apr 13 2019 01:04:33) ( NTS )

#########################################################################
composerをPHPのバージョンを指定してインストールした。
[example@sv9999 ~]$ curl -s https://getcomposer.org/installer | /usr/bin/php7.2
All settings correct for using Composer
Downloading...

Composer (version 1.9.0) successfully installed to: /home/example/composer.phar
Use it: php composer.phar

しかし、もともと入っていたんですか?????
[example@sv9999 ~]$ composer -v
______
/ ____/___ ____ ___ ____ ____ ________ _____
/ / / __ \/ __ `__ \/ __ \/ __ \/ ___/ _ \/ ___/
/ /___/ /_/ / / / / / / /_/ / /_/ (__ ) __/ /
\____/\____/_/ /_/ /_/ .___/\____/____/\___/_/
/_/
Composer version 1.8.5 2019-04-09 17:46:47

次に、ネットの情報を神頼みに composr init しました。
[example@sv9999 ~]$ composer init
Welcome to the Composer config generator

This command will guide you through creating your composer.json config.

Package name (<vendor>/<name>) [example/example]: composer
The package name composer is invalid, it should be lowercase and have a vendor name, a forward slash, and a package name, matching: [a-z0-9_.-]+/[a-z0-9_.-]+
Package name (<vendor>/<name>) [example/example]: q
The package name q is invalid, it should be lowercase and have a vendor name, a forward slash, and a package name, matching: [a-z0-9_.-]+/[a-z0-9_.-]+
Package name (<vendor>/<name>) [example/example]: exit
The package name exit is invalid, it should be lowercase and have a vendor name, a forward slash, and a package name, matching: [a-z0-9_.-]+/[a-z0-9_.-]+
Package name (<vendor>/<name>) [example/example]: \q
The package name \q is invalid, it should be lowercase and have a vendor name, a forward slash, and a package name, matching: [a-z0-9_.-]+/[a-z0-9_.-]+
Package name (<vendor>/<name>) [example/example]:
Description :
Author [, n to skip]: n
Minimum Stability
:
Package Type (e.g. library, project, metapackage, composer-plugin) :
License
:

Define your dependencies.

Would you like to define your dependencies (require) interactively [yes]?
Search for a package: smarty    /*smarty と打つのが大事*/

Found 13 packages matching smarty

[0] smarty/smarty
[1] slim/views
[2] michelf/php-smartypants
[3] dwoo/dwoo Abandoned. Use twig/twig instead.
[4] ytake/laravel-smarty
[5] yiisoft/yii2-smarty
[6] noiselabs/smarty-bundle
[7] smarty-gettext/smarty-gettext
[8] text/template
[9] smartystreets/phpsdk
[10] murganikolay/smarty-module
[11] mathmarques/smarty-view
[12] fireenginered/smartystreets-laravel

Enter package # to add, or the complete package name if it is not listed: 0 /*0と打つ*/
Enter the version constraint to require (or leave blank to use the latest version):

Using version ^3.1 for smarty/smarty
Search for a package: Would you like to define your dev dependencies (require-dev) interactively [yes]?
Search for a package:

{
"name": "example/example",
"require": {
"smarty/smarty": "^3.1"
}
}

Do you confirm generation [yes]?
Would you like to install dependencies now [yes]?
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
- Installing smarty/smarty (v3.1.33): Downloading (100%)
Writing lock file
Generating autoload files


PHPSpreadSheetをインストールする
[example@sv9999 ~]$ composer require phpoffice/phpspreadsheet
Using version ^1.9 for phpoffice/phpspreadsheet
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 4 installs, 0 updates, 0 removals
- Installing markbaker/matrix (1.1.4): Downloading (100%)
- Installing markbaker/complex (1.4.7): Downloading (100%)
- Installing psr/simple-cache (1.0.1): Downloading (100%)
- Installing phpoffice/phpspreadsheet (1.9.0): Downloading (100%)
phpoffice/phpspreadsheet suggests installing mpdf/mpdf (Option for rendering PDF with PDF Writer)
phpoffice/phpspreadsheet suggests installing dompdf/dompdf (Option for rendering PDF with PDF Writer)
phpoffice/phpspreadsheet suggests installing tecnickcom/tcpdf (Option for rendering PDF with PDF Writer)
phpoffice/phpspreadsheet suggests installing jpgraph/jpgraph (Option for rendering charts, or including charts with PDF or HTML Writers)
Writing lock file
Generating autoload files

これで使えるのか? かなり疑問が残ります。
[example@sv9999 ~]$ vi composer.json
{
"name": "example/example",
"require": {
"smarty/smarty": "^3.1",
"phpoffice/phpspreadsheet": "^1.9"
}
}
であるのを確認しました

[example@sv9999 ~]$ ls vendor/
autoload.php composer markbaker phpoffice psr smarty
であるのを確認

/vendor/autoload.php
/example.xsrv.jp/public_html/excel
の位置関係にあることをFTPでも確認しました

こんなので本当にEXCELファイル生成できるのか半信半疑なまま
https://blog.capilano-fw.com/?p=3945
こちらを拝見しながら、試してみることに...
test1.phpを作成しました。
require "../../../vendor/autoload.php";
$spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
$writer->save('test1.xlsx');
こんなPHPファイルを
/public_html/excel/の中に配置し、実行しましあら、あっさり test1.xlsx エクセルファイルが生成されていました!

次に test2.php を作成しました。
require "../../../vendor/autoload.php";
$spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->setCellValue('A1', 'テスト文字列');
$sheet->setCellValue('B1', 100);
$sheet->setCellValue('C1', true);
$sheet->setCellValue('D1', null); // 空白
$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
$writer->save('test2.xlsx');
こちらも思った通りの挙動の test2.xlsx エクセルファイルが生成されていました!

次に test3.php を作成しました。
テンプレートのエクセルファイルに 数値を入れ込む例です。帳票の作成などに使うためです。
require "../../../vendor/autoload.php";

$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader('Xlsx');
$spreadsheet = $reader->load('template1.xlsx');
$sheet = $spreadsheet->getActiveSheet();

$sheet->setCellValue('C5', '90');$sheet->setCellValue('D5', '95');
$sheet->setCellValue('C6', '70');$sheet->setCellValue('D6', '100');
$sheet->setCellValue('C7', '95');$sheet->setCellValue('D7', '78');

$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
$writer->save('test3.xlsx');
こちらも思った通りの挙動の test3.xlsx エクセルファイルが生成されていました!

次 行列 数値指定のパターン こちらの方が 実務的です
test4.php
require "../../../vendor/autoload.php";

$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader('Xlsx');
$spreadsheet = $reader->load('template1.xlsx');
$sheet = $spreadsheet->getActiveSheet();

$sheet->setCellValueByColumnAndRow( 3, 5, '90' );
$sheet->setCellValueByColumnAndRow( 4, 5, '95' );
$sheet->setCellValueByColumnAndRow( 3, 6, '70' );
$sheet->setCellValueByColumnAndRow( 4, 6, '100' );
$sheet->setCellValueByColumnAndRow( 3, 7, '95' );
$sheet->setCellValueByColumnAndRow( 4, 7, '78' );

$writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
$writer->save('test4.xlsx');
こちらも思った通りの挙動の test4.xlsx エクセルファイルが生成されていました!

行の削除は$sheet->removeRow(何行目か,何行分か);で良いようです。

思ったより、早く扱えて良かったです。体感的ですが、PHP EXCELはよっこらしょ という感じですが、サクサク動くように思いました。目出度し、目出度し!

今日は早起きし過ぎたので、ちょっと仮眠取らないと!