PHP快速读取docx文件为文本

{{ time }}

示例代码如下

/**
 * 读取docx文件为文本
 *  @param $source string 路径
 *  @param $limit int 限制字数
 */
function docx2txt($source, $limit = false)
{
    //找不到文件不行
    if (!$source || !file_exists($source))
        return false;

    //以zip方式打开
    $zip = zip_open($source);

    //格式不对不行
    if (!$zip || is_numeric($zip))
        return false;

    //读取zip中的每个文件
    while ($zip_entry = zip_read($zip)) {
        //打不开子文件不行
        if (zip_entry_open($zip, $zip_entry) == FALSE)
            continue;

        //只处理document.xml
        if (zip_entry_name($zip_entry) === "word/document.xml") {
            /**限制读取大小的情况 */
            if ($limit) {
                //superLimit和Step将影响读取性能

                //将limit放大10倍, 因为存在标签
                $superLimit = $limit * 10;

                //测试步长
                $step = 2000;

                $content = '';

                //用死循环来处理
                for ($i = 1; true; $i++) {
                    //得到继续读取的长度
                    $read = $i - 1 ? $step : $superLimit;

                    //读取
                    $content .= zip_entry_read($zip_entry, $read);

                    //本次循环得到的文本
                    $text = strip_tags($content);

                    //及其长度
                    $length = mb_strlen($text);

                    //当长度达到限定值时
                    if ($length >= $limit) {
                        $return = $length === $limit ? $text : mb_substr($text, 0, $limit);
                        break;
                    }
                }
            }

            /** 无限制大小的情况 */
            else {
                $content = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry));
                $return = strip_tags($content);
            }

            /**
             * 关闭entry:
             *   其实我想知道有没有必要关闭entry; 如果不用我在前面就return了
             */
            zip_entry_close($zip_entry);

            //处理后document.xml后, 不再继续遍历
            break;
        }
    }

    /**
     * 关闭zip文件:
     *   其实我想知道有没有必要关闭zip文件
     */
    zip_close($zip);

    return  $return;
}

//主函数
function main()
{
    header("Content-type:text/html; Charset=utf-8");

    //资源
    $source =  '/_server/wenku/public/test.docx';

    //读取前1000个字
    $begin = microtime(1);

    echo docx2txt($source, 1000);

    $lasting = microtime(1) - $begin;

    echo "<hr>用时{$lasting}秒";
}

//激活主函数
main();