2020年4月7日火曜日

PhpSpreadsheet をオフライン環境に導入する

昔にPHPExcelを使ったクローズなサービスを作っていた。
クローズというのは、インターネットから遮断されているということ。
このサービスを少し手直すする必要が出てきた。
寝ている子を起こすといやつだ。
どうやらPHPExcelはもう推奨されていないらしい
https://github.com/PHPOffice/PHPExcel
https://qiita.com/suin/items/7a8d0979b7675d6fd05b
「PhpSpreadsheet」というのが後継にあるのかな。
https://phpspreadsheet.readthedocs.io/en/latest/
https://github.com/PHPOffice/PhpSpreadsheet

環境

開発環境はlinuxで、上記のサービス環境はwindowsという変な状態になっている。
windows環境はインターネットからは遮断されており、検査されたデータしか持ち込めない。
しかも手動検査・都度申請が必要…

PhpSpreadsheet の公式インストール方法

公式では、composerを使って
composer require phpoffice/phpspreadsheet
php -S localhost:8000 -t vendor/phpoffice/phpspreadsheet/samples
で一撃的な感じで書いてある。
composerねー。npmもそうだけど、オフライン環境への導入が大変そう。
みんなはどうしているのかな? 巨人の肩に乗らせて欲しい
まずは、公式の手順でやってみる

早速サンプルを実行してみる

php -S localhost:8888 -t vendor/phpoffice/phpspreadsheet/samples


ディレクトリ構成

これで、一体どのようなファイル生成されているかを見てみよう
:~/excel$ tree
.
├── composer.json
├── composer.lock
└── vendor
    ├── autoload.php
    ├── composer
    │   ├── ClassLoader.php
    │   ├── LICENSE
    │   ├── autoload_classmap.php
    │   ├── autoload_files.php
    │   ├── autoload_namespaces.php
    │   ├── autoload_psr4.php
    │   ├── autoload_real.php
    │   ├── autoload_static.php
    │   └── installed.json
    ├── markbaker
    │   ├── complex
    │   └── matrix
    ├── phpoffice
    │   └── phpspreadsheet
    │       ├── CHANGELOG.PHPExcel.md
    │       ├── CHANGELOG.md
    │       ├── CONTRIBUTING.md
    │       ├── LICENSE
    │       ├── bin
    │       ├── composer.json
    │       ├── composer.lock
    │       ├── docs
    │       ├── mkdocs.yml
    │       ├── phpunit.xml.dist
    │       ├── samples
    │       └── src
    └── psr
        └── simple-cache
            ├── LICENSE.md
            ├── README.md
            ├── composer.json
            └── src
なるほど・・・。
vender配下に生成するのと、autoload.phpが肝なのか?

Composerをオフラインで使う

調べてみると、オンラインPCでComposerを使用して必要なライブラリなどを取得して環境を作って、それをオフライン環境に導入するといった方法が多いみたい
https://teratail.com/questions/76493
https://blitzgate.co.jp/blog/1820/
上記を踏まえて作戦を考えた
  1. ローカルのリポジトリ的なやつからインストール
  2. 手動で依存関係を解決する
  3. オンラインPC環境で構築してから転送する

ローカルのリポジトリからインストール

https://qiita.com/suin/items/d24c2c0d8c221ccbc2f3
windows版のcomposerをインストールするハードルがあるが、出来てしまえば、応用がききそう。
今回は時間が無いので、見送る。

手動で依存関係を解決してみる

依存関係の定義

依存関係はcomposer.jsonに定義しているみたい
    "require": {
        "php": "^7.1",
        "ext-ctype": "*",
        "ext-dom": "*",
        "ext-gd": "*",
        "ext-iconv": "*",
        "ext-fileinfo": "*",
        "ext-libxml": "*",
        "ext-mbstring": "*",
        "ext-SimpleXML": "*",
        "ext-xml": "*",
        "ext-xmlreader": "*",
        "ext-xmlwriter": "*",
        "ext-zip": "*",
        "ext-zlib": "*",
        "markbaker/complex": "^1.4",
        "markbaker/matrix": "^1.2",
        "psr/simple-cache": "^1.0"
    },

ベースとなるディレクトリ構造

まずは、この構造を作る
:~/excel$ tree
.
└── vendor
    ├── markbaker
    │   ├── complex
    │   └── matrix
    ├── phpoffice
    │   └── phpspreadsheet
    └── psr
        └── simple-cache
それぞれを手動でインストールしてみようと試みた。
名称 ソース
PHPComplex https://github.com/MarkBaker/PHPComplex
PHPMatrix https://github.com/MarkBaker/PHPMatrix
simple-cache https://github.com/php-fig/simple-cache
phpspreadsheet https://github.com/PHPOffice/PhpSpreadsheet
composer関係を除けば同じようになった。

サンプルを実行してみる

これで動けばいいのだけれど
$ php -S localhost:8888 -t vender/phpoffice/phpspreadsheet/samples
PHP 7.2.24-0ubuntu0.18.04.3 Development Server started at Sun Mar 15 09:52:56 2020
Listening on http://localhost:8888
Document root is /***/vender/phpoffice/phpspreadsheet/samples
Press Ctrl-C to quit.
[Sun Mar 15 09:53:12 2020] PHP Fatal error:  Uncaught Exception: Composer autoloader could not be found. Install dependencies with `composer install` and try again. in /***/vender/phpoffice/phpspreadsheet/src/Bootstrap.php:22
Stack trace:
#0 /***/vender/phpoffice/phpspreadsheet/samples/Header.php(9): require_once()
#1 /***/vender/phpoffice/phpspreadsheet/samples/index.php(3): require_once('/home/adeno/exc...')
#2 {main}
  thrown in /***/vender/phpoffice/phpspreadsheet/src/Bootstrap.php on line 22
[Sun Mar 15 09:53:12 2020] 127.0.0.1:39226 [500]: / - Uncaught Exception: Composer autoloader could not be found. Install dependencies with `composer install` and try again. in /***/vender/phpoffice/phpspreadsheet/src/Bootstrap.php:22
Stack trace:
#0 /***/vender/phpoffice/phpspreadsheet/samples/Header.php(9): require_once()
#1 /***/vender/phpoffice/phpspreadsheet/samples/index.php(3): require_once('/home/adeno/exc...')
#2 {main}
  thrown in /***/vender/phpoffice/phpspreadsheet/src/Bootstrap.php on line 22

あら、、、
Composer autoloader could not be found

オンラインPC環境で構築してから転送する

他のPCで環境構築したものを持ってくるのは最終手段にしたかったが、仕方ない。
linuxで環境構築した一式をwindows側に持ってくる。
php -S localhost:8888 -t vendor\phpoffice\phpspreadsheet\samples


なんと、一撃だった。

肝心な使い方

おいおいと
https://symfoware.blog.fc2.com/blog-entry-2059.html
https://vertys.net/php-spreadsheet-often-use-process/
https://qiita.com/BRSF/items/ed32311d48161be7c719
https://blog.capilano-fw.com/?p=3945#i-16
https://qiita.com/sudnonk12/items/a0d58cc0f6ff1c6e2765
http://ariarijp.hatenablog.com/entry/2017/08/24/093000
https://knooto.info/php-phpexcel-vs-phpspreadsheet/
とりあえずサンプル+追記で今日はここまで。
<?php

require 'vendor/autoload.php';

use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use PhpOffice\PhpSpreadsheet\Style\Border;
use PhpOffice\PhpSpreadsheet\Style\Fill;
use PhpOffice\PhpSpreadsheet\Style\Style;

$spreadsheet = new Spreadsheet();

// Set document properties
$spreadsheet->getProperties()->setCreator('Adeno')
    ->setLastModifiedBy('Adeno')
    ->setTitle('タイトル')
    ->setSubject('件名')
    ->setDescription('コメント')
    ->setKeywords('キーワード');

$sheet = $spreadsheet->getActiveSheet();
$sheet->setCellValue('A1', 'Hello World !');
$sheet->setCellValue('A2', '日本語はどう?');
$sheet->unFreezePane();


// Rename worksheet
$spreadsheet->getActiveSheet()->setTitle('シート1');


$sheet = $spreadsheet->createSheet(1);
$sheet->setCellValue('A1', '2枚めHello World !');
$sheet->setCellValue('A2', 'No');
$sheet->setCellValue('B2', '名前');
$sheet->setCellValue('C2', '単価');
$sheet->setCellValue('D2', '数量');
$sheet->setCellValue('E2', '小計');
$sheet->setTitle('シート2');

// スタイルを指定
$sharedStyle = new Style();
    $sharedStyle->applyFromArray([
        'borders' => [
            'top' => ['borderStyle' => Border::BORDER_THIN],
            'bottom' => ['borderStyle' => Border::BORDER_THIN],
            'right' => ['borderStyle' => Border::BORDER_THIN],
            'left' => ['borderStyle' => Border::BORDER_THIN],
        ]
    ]
);


$sheet->duplicateStyle($sharedStyle, 'A2:E3');

$sheet->freezePane('A2');   //1行目を固定

// Set active sheet index to the first sheet, so Excel opens this as the first sheet
$spreadsheet->setActiveSheetIndex(0);


$writer = new Xlsx($spreadsheet);

// Redirect output to a client’s web browser (Xlsx)
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="01simple.xlsx"');
header('Cache-Control: max-age=0');
// If you're serving to IE 9, then the following may be needed
header('Cache-Control: max-age=1');


//$writer = IOFactory::createWriter($spreadsheet, 'Xlsx');
$writer->save('php://output');
exit;
こんな感じ

0 件のコメント:

コメントを投稿