やりたいこと
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);
まとめ
やりたいことに対応するタグ要素さえ見つけられれば、紹介したコードで応用が利くと思います。