📁

【PHP】docx, xlsx, pptxのテキストを取得する

4 min read

この記事はGAOGAO Advent Calendar 2021 ことしもGAOGAOまつりです の6日目の記事です。

昨日の記事は、【AWS認定】ソリューションアーキテクト - アソシエイト 英語受験のすゝめ(SAA-C02)でした。

はじめに

こんにちは。今月から神戸に移住したしまむらです。
世界中でモノつくりの連鎖を起こすスタートアップスタジオGAOGAOでソフトウェアエンジニアをしています。

この記事では、オフィス系のファイル(Word, Excel, PowerPoint)からテキストを抽出するサンプルコードを記述していきます。

ZipArchiveクラスを使用しています。

以下のようなライブラリもありますが、単にテキストを取得する場合の良い実装例が見当たらなかった背景があります(見落としていただけかも知れませんが...)

その前に...

Office Open XML(OOXML)


XMLに準拠したファイル形式。
Microsoft Word, Excel, Powerpointはすべてこれに倣ってファイルが作成されています。

ファイルに存在するテキストは、XMLの内部に存在します。
OOXMLの実態はZIPアーカイブなので、解凍すると中身を展開できます。

OOXMLの中身

Word(.docx)

Excel(.xlsx)

PowerPoint(.pptx)

実装例

実行環境

  • Mac OS Monterey (12.0.1)
  • PHP 8.0.8

Word(docx)の場合

  • word/document.xml からテキストを取得します
getTextFromDocx.php
<?php

function getTextFromDocx(string $filePath): string
{
    $zip = new ZipArchive;
    $result = '';

    if ($zip->open($filePath) === true) {
        $documentXml = $zip->getFromName("word/document.xml");
        if ($documentXml) {
            $domDocument = new DOMDocument();
            $domDocument->loadXML($documentXml);
            $paragraphs = $domDocument->getElementsByTagName("p");
            /** @var DOMNode $paragraph */
            foreach ($paragraphs as $paragraph) {
                $result .= $paragraph->textContent;
            }
        }
    }

    return $result . "\n";
}

echo getTextFromDocx('./test.docx');

結果

Excel(xslx)の場合

  • xl/sharedStrings.xml からテキストを取得します
getTextFromXlsx.php
<?php

function getTextFromXlsx(string $filePath): string
{
    $zip = new ZipArchive;
    $response = '';

    $open = $zip->open($filePath);
    if ($open === true) {
        $sharedStringsXml = $zip->locateName('xl/sharedStrings.xml');
        if ($sharedStringsXml) {
            $domDocument = new DOMDocument;
            $xml = $zip->getFromIndex($sharedStringsXml);
            $domDocument->loadXML($xml, LIBXML_NOENT | LIBXML_XINCLUDE | LIBXML_NOERROR | LIBXML_NOWARNING);
            $response .= strip_tags($domDocument->saveXML());
        }
        $zip->close();
    }

    return $response;
}

echo getTextFromXlsx('./test.xlsx');

結果

PowerPoint(pptx)の場合

getTextFromPptx.php
<?php

function getTextFromPptx(string $filePath): string
{
    $zip = new ZipArchive;
    $response = '';

    $open = $zip->open($filePath);

    if ($open === true) {
        $slideNumber = 1;
        $doc = new DOMDocument;
        while (($xmlIndex = $zip->locateName('ppt/slides/slide' . $slideNumber . '.xml')) !== false) {
            $xmlData   = $zip->getFromIndex($xmlIndex);
            $doc->loadXML($xmlData, LIBXML_NOENT | LIBXML_XINCLUDE | LIBXML_NOERROR | LIBXML_NOWARNING);
            $response .= strip_tags($doc->saveXML());
            $slideNumber++;
        }
        $zip->close();
    }

    return $response;
}

echo getTextFromPptx('./test.pptx');

結果

さいごに

今回のサンプルコードはこちらのリポジトリからアクセスできます。
テスト用のファイルも同梱してあるので、コマンドラインから実際に実行できます。

https://github.com/smtrdev/php-ooxml-get-text

参考記事

Discussion

ログインするとコメントできます