ブログ
これまでに経験してきたプロジェクトで気になる技術の情報を紹介していきます。
xlsmファイルの特定シートの値を取得したい
Yamanaka
3 years
クライアントエンジニアもしていますが、 今回はサーバ側のCMSの開発を行っている山中です。
データベースのデータ更新をcsvファイルからCMSへインポートして行っていました。 インポートするcsvファイルはExcelファイルから作成しています。
csvファイルを経由せずに直接Excelファイルをインポート出来ないか探したところ、 PHPExcelやPhpSpreadsheetばかり...
自分で作ってみたいのでもう少し調べてみたところ、 どうやらExcelファイルは拡張子次第でzip解凍できるみたいです。
なのでExcelファイルのパスと展開後のシートのパス(xl/worksheets/sheet1.xml等)を引数にカラムと値の配列を返す関数を作成しました。
文字列が保存されたsharedStrings.xmlから文字を取り出し、 指定シートからカラムと番号を取り出して、カラムをキーにして番号にあった文字列を値とします。 t="s"が無ければ文字列ではないと判断して番号を値とします。
問題点として、Excel関数を使用している所では使用できませんが...
とりあえず、目的は達成出来たのでコレで解決! 作成した関数は以下となります。
// Excelのシートのデータを取得する
public function GetXlsmSheetData($excelPath, $sheetPath){
// 文字列が保存されたファイル
$filePath = 'xl/sharedStrings.xml';
// ファイルを取りだす
exec("unzip -p ".$excelPath ." ". $filePath , $res);
$res = join("\n",$res);
// 文字列の塊ごとに分割
$res = explode('<si>', $res);
$strList = [];
$isFirst = true;
foreach ($res as $data){
// 分割が塊の始まり部分で行っている為最初は不要
if($isFirst){
$isFirst = false;
continue;
}
$data = explode('</t>', $data);
$strList[] = explode('>', $data[0])[1] ?? '';
}
// シート情報のファイルを取りだす
exec("unzip -p ".$excelPath ." ". $sheetPath , $sheetData);
$sheetData = join("\n",$sheetData);
// カラムの塊ごとに分割
$sheetData = explode('<c r="', $sheetData);
$sheetList = [];
$isFirst = true;
foreach ($sheetData as $data){
// 分割が塊の始まり部分で行っている為最初は不要
if($isFirst){
$isFirst = false;
continue;
}
$colume = explode('"', $data)[0] ?? '';
// 文字列か
$isStr = strpos($data, 't="s"');
// 値取得
$data = explode('<v>', $data);
if(count($data) < 2){
$sheetList[$colume] = '';
continue;
}
$data = explode('</v>', $data[1]);
if($isStr){
// 文字列
$sheetList[$colume] = $strList[$data[0]] ?? '';
} else {
// 数値
$sheetList[$colume] = $data[0];
}
}
return $sheetList;
}
以上 山中がお伝えしました。またお会いしましょう!
参考URL https://wordpress.ideacompo.com/?p=12409 https://www.geekfeed.co.jp/geekblog/exceldisassembly/
xlsmファイルの特定シートの値を取得したい
xlsmファイルの特定シートの値を取得したい
2021-05-27 09:07:41
2021-08-18 04:14:00
コメントはありません。