xlsmファイルの特定シートの値を取得したい

クライアントエンジニアもしていますが、 今回はサーバ側の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/

Yamanaka

Programmer

xlsmファイルの特定シートの値を取得したい

お気軽に
お問い合わせください。

お問い合わせ