Help us understand the problem. What is going on with this article?

【PHP】プログラムからMS Wordのドキュメントファイルを読み込む

PHPでWEBシステム制作の案件を処理していると、まれにwordのドキュメントファイルを読み込まないといけないという案件があったりします。ですが、Wordのドキュメントファイルに書き込むことを前提としたPHP-wordの使用方法はちらほら出てくるのですが、あくまでPHP上のデータをWord上に書き込むだけであり、逆にWordのドキュメントファイルを読み込むという方法がなかなか出てきません。

そこで、色々と検索ワードを考えて海外サイトも含め巡回した成果を記録していきたいと思います。

Wordのdocxファイルを読み込む

docxファイルはWord2007から主流となっている、XMLを使用したファイルです。なので、PHPでXMLを読み込めるように対処すれば普通に読み込めてしまったりします。

これは、自分が公開しているPhpspreadsheetに関する記事ですが、こちらもxlsxファイルを読み込むためにphp-zipとlibzip5ライブラリをインストールしているので、今度の場合もdocxファイルを読み込むために同じライブラリをインストールしておきます。

/*PHP7.1以前はこちら*/
hogehoge$ yum --enablerepo=remi-phpxx -y install php-zip libzip5
/*PHP7.2以降はこちら*/
hogehoge$ yum --enablerepo=remi-phpxx -y install php-pecl-zip libzip5
hogehoge$ systemctl restart httpd //Apacheの場合、Nginxならhttpdをnginxに書き替える
hogehoge$ php --ri zip//zip関連のアーカイブがインストールされているか確認
/*このように表示されていれば確実*/

zip

Zip => enabled
Zip version => x.x.x
Libzip headers version => x.x.x
Libzip library version => x.x.x

docxファイルを読み込む

あとはZipArchiveクラスを用いるだけです。

ZipArchive クラス

docx.jpg

PHP
$filename = "test.docx"; //対象となるdocxファイル
 $zip = zip_open($filename);
 $content = "";
if ($zip && !is_numeric($zip)){
    while ($zip_entry = zip_read($zip)) {
       if (zip_entry_open($zip, $zip_entry) == FALSE) continue;
       if (zip_entry_name($zip_entry) != "word/document.xml") continue;
       $content .= zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));
       zip_entry_close($zip_entry);
    }
}
zip_close($zip);
$content = preg_replace("/\<\/w:t\>/","<br>",$content); //改行にあたる部分だけを置き換える
echo $content;

これで後はブラウザに表示するだけです。ただ、元のソースのままだと改行が行われなかったので、改行が行われるように修正を加えています。また、ソースを見るとまだまだ無駄なタグがあるので、それを必要に応じて置換するといいでしょう。

browse.jpg

参考にしたページ

How to extract text from word file .doc,docx,.xlsx,.pptx php

Wordのdocファイルを読み込む

docファイルはマイクロソフト社が独自で開発した規格のため、かなりの人が処理に悪戦苦闘しているようですが、実はfile関数を使って開くことができるようです。ですが、そこからのエンコードに苦戦しているようで、いろいろなサイトで方法を公開していますが、的確に処理できていた記述は上記のリンクにあった方法だけでした。

document2.jpg

PHP
$filename = "test.doc"; //テスト用のドキュメントファイル
if(file_exists($filename)){
    if(($fh = fopen($filename, 'r')) !== false ){
       $headers = fread($fh, 0xA00);
       // 1 = (ord(n)*1) ; Document has from 0 to 255 characters
       $n1 = ( ord($headers[0x21C]) - 1 );
       // 1 = ((ord(n)-8)*256) ; Document has from 256 to 63743 characters
       $n2 = ( ( ord($headers[0x21D]) - 8 ) * 256 );
       // 1 = ((ord(n)*256)*256) ; Document has from 63744 to 16775423 characters
       $n3 = ( ( ord($headers[0x21E]) * 256 ) * 256 );
       // 1 = (((ord(n)*256)*256)*256) ; Document has from 16775424 to 4294965504 characters
       $n4 = ( ( ( ord($headers[0x21F]) * 256 ) * 256 ) * 256 );
       // Total length of text in the document
       $textLength = ($n1 + $n2 + $n3 + $n4);
       $text = fread($fh, $textLength);
       nl2br($text);
       $text = preg_replace('/[\x00-\x09\x0B\x0C\x0E-\x1F\x7F]/',"",$text); //制御記号を置換
       echo $text;
    }
}   

ただ、それだけだと制御文字まで表示されてしまっていたので、置換処理を施しています。

browse2.jpg

※あくまでStack Overflowでの記事なので、日本語までは対応していません。いちおう文字化けした状態では出力されるのですが、エンコードができずに苦戦しています。もし、解決方法をご存知の方はアンサーをいただけると大変助かります。

Apache POIを使用する方法もあるようですが、そもそもどうやってcentOS7にインストールしたらいいのかが詰まっており、しかも、そこからPHPと連携する方法、docファイルを取得する方法がわかっていませんし、果たして日本語を取得できるのかどうかもわかりませんが、業務の合間を見て分析を続けていきたいところです。

BRSF
職業、PG・SE・DBエンジニア。オープン環境のwebプログラムをメインにシステム構築担当。使用言語はPHP(cakePHP、Laravel含)jQuery、JavaScript、ExcelVBA、Perl、Ruby、Python。現在Vue、React、Angular強化中。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした