[PHP] Wordファイル.docxの文字数をカウントする(取り消しやコメントも取得可能)

PHP

やりたいこと

PHPを使って、Wordファイル.docxの文字数をカウントしたい。
まずは、本文の文字数カウントのやり方を紹介します。
応用編として、取り消された文字やコメントの文字を取得するコードを紹介します。

環境

  • PHP 8.0.0
  • Windows 10

手順

1: .docxファイルを解凍して、.xmlファイルを拾う。

実際にzipファイルを見るとわかりますが、目的のファイルは、wordフォルダ内のdocument.xmlです。

2: 段落(pタグ)ごとに、テキスト(tタグ)を連結していく。

getElementsByTagNameメソッドで、所望のタグ要素を取得できます。

3: 連結した文字列の文字数を数える。

文字数のカウントにはmb_strlen()関数を使います。

コード

$NL = "\n";
$contents = "";
$file_path = $request->file("testFile"); // フォームで受け取る想定です。
$zip = new \ZipArchive();
if ($zip->open($file_path) === true) {
    $xml = $zip->getFromName("word/document.xml");
    if ($xml) {
          $dom = new \DOMDocument();
          $dom->loadXML($xml);
        // 段落(pタグ)抽出
        $paragraphs = $dom->getElementsByTagName("p");
          foreach ($paragraphs as $p) {
            // テキスト(tタグ)抽出
              $texts = $p->getElementsByTagName("t");
              foreach ($texts as $t) {
                $contents .= $t->nodeValue;
              }
          }
    }
}
$wordscount = mb_strlen($contents);

応用

上記のやり方だと、取り消し線で消された文字や、コメントの文字が拾えない。
そこで、取り消し線で消された文字はdelTextタグ、コメントはword/comments.xmlから拾ってくる。
下記がそれらを含んだコード。

$NL = "\n";
$contents = "";
$file_path = $request->file("testFile"); // フォームで受け取る想定です。
$zip = new \ZipArchive();
if ($zip->open($file_path) === true) {
    // 本文の文字列を抽出
    $xml = $zip->getFromName("word/document.xml");
    if ($xml) {
          $dom = new \DOMDocument();
          $dom->loadXML($xml);
        // 段落(pタグ)抽出
        $paragraphs = $dom->getElementsByTagName("p");
          foreach ($paragraphs as $p) {
            // テキスト(tタグ)抽出
              $texts = $p->getElementsByTagName("t");
              foreach ($texts as $t) {
                $contents .= $t->nodeValue;
              }
            // 取り消しされたテキスト(delTextタグ)抽出
            $delTexts = $p->getElementsByTagName("delText");
              foreach ($delTexts as $dt) {
                  $contents .= $dt->nodeValue;
              }
              $contents .= $NL;
          }
    }
    // コメントの文字列を抽出
    $xmlComment = $zip->getFromName("word/comments.xml");
    if ($xmlComment) {
        $dom = new \DOMDocument();
        $dom->loadXML($xmlComment);
      // 段落(pタグ)抽出
        $paragraphs = $dom->getElementsByTagName("p");
        foreach ($paragraphs as $p) {
        // テキスト(tタグ)抽出
            $texts = $p->getElementsByTagName("t");
            foreach ($texts as $t) {
                $contents .= $t->nodeValue;
            }
        // 取り消しされたテキスト(delTextタグ)抽出
        $delTexts = $p->getElementsByTagName("delText");
            foreach ($delTexts as $dt) {
                $contents .= $dt->nodeValue;
            }
            $contents .= $NL;
        }
    }
}
$wordscount = mb_strlen($contents);

まとめ

やりたいことに対応するタグ要素さえ見つけられれば、紹介したコードで応用が利くと思います。

タイトルとURLをコピーしました