📁

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

2021/12/06に公開

この記事は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