🍑
[PHP]PHPExcelでテンプレートシートの要素を必要なだけコピーする
概要
- PHPExcelでテンプレートシートの要素を必要なだけコピーするサンプルコード
- 関数や罫線のコピーにも対応してます
コード
以下のコードは、基準行(5行目)の内容を、必要な分だけその下の行にコピーする内容となっています。
<?php
// ライブラリの読み込み
require_once '/usr/lib/PHPExcel/Classes/PHPExcel.php';
require_once '/usr/lib/PHPExcel/Classes/PHPExcel/IOFactory.php';
// タイムゾーンの設定
date_default_timezone_set('Asia/Tokyo');
// 出力内容のオリジナルデータ: 今回は同じ形式の内容がjsonファイルに記載されているものとする
$json = file_get_contents('xxx.json');
// 配列形式に変換
$contents = json_decode($json, true);
// テンプレートとなるExcelファイル名
$template = 'template.xlsx';
// テンプレートの開始行(この行にコピーすべき内容が記載されているものとする)
$templateStart = 5;
// ファイルタイプ
$fileType = 'Excel2007';
// 出力ファイル名
$newFile = 'abc.xlsx';
$reader = PHPExcel_IOFactory::createReader($fileType);
$excel = $reader->load($template);
// テンプレートの書き込みシート名
$sheet = $excel->getSheetByName('yyy');
// 添付シ-トの最終列を取得し、数字に変換
$lastColumnIndex = PHPExcel_Cell::columnIndexFromString($sheet->getHighestColumn());
// データ出力開始行は関数、スタイルとも設定済のため次の行が開始ライン
$nextRow = $templateStart + 1;
// データ出力最終行
$lastRow = $templateStart + count($contents) - 2;
// コピー処理
for ($i = $nextRow; $i <= $lastRow; $i++) {
for ($j = 0; $j <= $lastColumnIndex; $j++) {
// 最終列をアルファベット→インデックス(整数)に変換 スタイルの複製が列、行ベースでできないっぽいため
$column = PHPExcel_Cell::stringFromColumnIndex($j);
// 埋め込み関数を基準行から一通りコピーする
$sheet->setCellValueByColumnAndRow($j, $i, str_replace($templateStart, $i, $cellValue));
// 罫線などのスタイルも基準行に合わせる:
$sheet->duplicateStyle($sheet->getCell("{$column}{$templateStart}")->getStyle(), "{$column}{$i}");
}
}
// 印刷範囲設定(最終列がAT列で固定の場合)
$sheet->getPageSetup()->setPrintArea("A1:AT$lastRow");
/*
書き込み処理: 出力内容のオリジナルデータを適切な箇所に書き込む
*/
$writer = PHPExcel_IOFactory::createWriter($excel, $fileType);
$writer->save($newFile);
今回のポイント
- 埋め込み関数のコピーと罫線などのスタイルの複製
対象箇所を抜粋
// 埋め込み関数を基準行から一通りコピーする
$sheet->setCellValueByColumnAndRow($j, $i, str_replace($templateStart, $i, $cellValue));
// 罫線などのスタイルも基準行に合わせる:
$sheet->duplicateStyle($sheet->getCell("{$column}{$templateStart}")->getStyle(), "{$column}{$i}");
終わりに
使用環境でPHPExcelを用いているため、ひとまずこちらのみUPしました
PhpSpreadsheetでもほぼ同じやり方でできると思います
サンプルコードができたらそちらも記載します
参考
更新履歴
- 2022/05/03: 印刷範囲設定を追加
Discussion