PHP项目Word内容如何提取纯文本信息

wen PHP项目 31

本文目录导读:

PHP项目Word内容如何提取纯文本信息

  1. 方法一:使用 PHPWord 库(推荐)
  2. 方法二:使用正则表达式提取.docx中的XML文本
  3. 方法三:使用系统命令(需服务器支持)
  4. 方法四:使用 phpdocx 库(商业版)
  5. 完整解决方案(推荐)
  6. 性能优化建议

在PHP项目中提取Word文档(.docx)的纯文本信息,有几种常用的方法,我将按推荐程度和实用性为你介绍。

使用 PHPWord 库(推荐)

这是最常用且功能完善的方案。

安装

composer require phpoffice/phpword

提取纯文本

<?php
require 'vendor/autoload.php';
use PhpOffice\PhpWord\IOFactory;
function extractTextFromWord($filePath) {
    try {
        // 加载 Word 文档
        $phpWord = IOFactory::load($filePath);
        // 提取纯文本
        $text = '';
        foreach ($phpWord->getSections() as $section) {
            foreach ($section->getElements() as $element) {
                if (method_exists($element, 'getText')) {
                    $text .= $element->getText() . "\n";
                }
                // 处理表格
                if ($element instanceof \PhpOffice\PhpWord\Element\Table) {
                    foreach ($element->getRows() as $row) {
                        foreach ($row->getCells() as $cell) {
                            foreach ($cell->getElements() as $cellElement) {
                                if (method_exists($cellElement, 'getText')) {
                                    $text .= $cellElement->getText() . "\t";
                                }
                            }
                            $text .= "\n";
                        }
                    }
                }
                // 处理列表
                if ($element instanceof \PhpOffice\PhpWord\Element\ListItem) {
                    $text .= $element->getText() . "\n";
                }
            }
            $text .= "\n--- 新段落 ---\n";
        }
        return trim($text);
    } catch (Exception $e) {
        return "提取失败: " . $e->getMessage();
    }
}
// 使用示例
$file = 'document.docx';
$plainText = extractTextFromWord($file);
echo $plainText;

简化版本(只提取主要文本)

function simpleTextExtract($filePath) {
    $phpWord = \PhpOffice\PhpWord\IOFactory::load($filePath);
    $text = '';
    // 获取所有文本元素
    foreach ($phpWord->getSections() as $section) {
        $elements = $section->getElements();
        foreach ($elements as $element) {
            if ($element instanceof \PhpOffice\PhpWord\Element\TextRun ||
                $element instanceof \PhpOffice\PhpWord\Element\Title) {
                $text .= $element->getText() . ' ';
            }
        }
    }
    return trim($text);
}

使用正则表达式提取.docx中的XML文本

.docx 文件本质上是 ZIP 压缩包,包含 XML 文件。

<?php
function extractTextFromDocx($filePath) {
    if (!file_exists($filePath)) {
        return "文件不存在";
    }
    // 打开 ZIP 文件
    $zip = new ZipArchive();
    if ($zip->open($filePath) === true) {
        // 读取文档内容
        $content = $zip->getFromName('word/document.xml');
        $zip->close();
        if ($content === false) {
            return "无法读取文档内容";
        }
        // 移除 XML 标签,提取纯文本
        $content = strip_tags($content);
        // 解码 HTML 实体
        $content = html_entity_decode($content, ENT_QUOTES, 'UTF-8');
        // 清理多余的空白
        $content = preg_replace('/\s+/', ' ', $content);
        $content = preg_replace('/\n\s*\n/', "\n", $content);
        return trim($content);
    } else {
        return "无法打开文件";
    }
}
// 使用示例
$text = extractTextFromDocx('document.docx');
echo $text;

使用系统命令(需服务器支持)

Linux 使用 antiwordcatdoc

<?php
function extractWordTextLinux($filePath) {
    // 方法1:使用 antiword
    $text = shell_exec("antiword '$filePath'");
    // 方法2:使用 catdoc
    // $text = shell_exec("catdoc '$filePath'");
    // 方法3:使用 libreoffice 转换
    // $output = tempnam(sys_get_temp_dir(), 'wordtxt');
    // shell_exec("libreoffice --headless --convert-to txt:Text '$filePath' --outdir " . dirname($output));
    // $text = file_get_contents($output);
    // unlink($output);
    return $text;
}

Windows 使用 PowerShell

<?php
function extractWordTextWindows($filePath) {
    $command = "powershell -Command \"Add-Type -AssemblyName Microsoft.Office.Interop.Word; " .
               "\$word = New-Object -ComObject Word.Application; " .
               "\$doc = \$word.Documents.Open('$filePath'); " .
               "\$text = \$doc.Content.Text; " .
               "\$doc.Close(); " .
               "\$word.Quit(); " .
               "Write-Output \$text\"";
    return shell_exec($command);
}

使用 phpdocx 库(商业版)

<?php
require_once 'phpdocx/classes/Phpdocx.class.php';
$doc = new Phpdocx();
$text = $doc->extractWordText('document.docx');
echo $text;

完整解决方案(推荐)

这是一个更完善的、处理多种情况的类:

<?php
require 'vendor/autoload.php';
class WordTextExtractor {
    /**
     * 提取 Word 文档中的纯文本
     * 
     * @param string $filePath Word 文件路径
     * @param bool $preserveLineBreaks 是否保留换行
     * @return string
     */
    public function extract($filePath, $preserveLineBreaks = true) {
        if (!file_exists($filePath)) {
            throw new \InvalidArgumentException("文件不存在: $filePath");
        }
        $extension = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
        switch ($extension) {
            case 'docx':
                return $this->extractDocx($filePath, $preserveLineBreaks);
            case 'doc':
                return $this->extractDoc($filePath);
            default:
                throw new \InvalidArgumentException("不支持的文件格式: $extension");
        }
    }
    /**
     * 提取 .docx 文件
     */
    private function extractDocx($filePath, $preserveLineBreaks) {
        $phpWord = \PhpOffice\PhpWord\IOFactory::load($filePath);
        $text = '';
        foreach ($phpWord->getSections() as $section) {
            foreach ($section->getElements() as $element) {
                $text .= $this->processElement($element);
            }
            if ($preserveLineBreaks) {
                $text .= "\n";
            }
        }
        return $this->cleanText($text);
    }
    /**
     * 处理文档元素
     */
    private function processElement($element) {
        $text = '';
        if ($element instanceof \PhpOffice\PhpWord\Element\TextRun) {
            $text .= $element->getText();
        } elseif ($element instanceof \PhpOffice\PhpWord\Element\Title) {
            $text .= $element->getText() . "\n";
        } elseif ($element instanceof \PhpOffice\PhpWord\Element\ListItem) {
            $text .= "- " . $element->getText() . "\n";
        } elseif ($element instanceof \PhpOffice\PhpWord\Element\Table) {
            $text .= $this->processTable($element);
        } elseif ($element instanceof \PhpOffice\PhpWord\Element\TextBreak) {
            $text .= "\n";
        }
        return $text;
    }
    /**
     * 处理表格
     */
    private function processTable($table) {
        $text = "\n";
        foreach ($table->getRows() as $row) {
            foreach ($row->getCells() as $cellIndex => $cell) {
                $cellText = '';
                foreach ($cell->getElements() as $cellElement) {
                    if ($cellElement instanceof \PhpOffice\PhpWord\Element\TextRun) {
                        $cellText .= $cellElement->getText();
                    }
                }
                $text .= $cellText . "\t";
            }
            $text .= "\n";
        }
        $text .= "\n";
        return $text;
    }
    /**
     * 提取 .doc 文件(需要服务器安装 LibreOffice)
     */
    private function extractDoc($filePath) {
        // 对于旧版 .doc 格式,建议先转换为 .docx
        $tempPath = tempnam(sys_get_temp_dir(), 'docx') . '.docx';
        $command = "libreoffice --headless --convert-to docx " . 
                   escapeshellarg($filePath) . " --outdir " . 
                   escapeshellarg(dirname($tempPath));
        exec($command, $output, $returnCode);
        if ($returnCode === 0) {
            $text = $this->extractDocx($tempPath, true);
            unlink($tempPath);
            return $text;
        }
        throw new \RuntimeException("无法转换 .doc 文件");
    }
    /**
     * 清理文本
     */
    private function cleanText($text) {
        // 移除多余的空行
        $text = preg_replace("/\n{3,}/", "\n\n", $text);
        // 移除行首尾的空白
        $text = preg_replace("/[ \t]+$/m", "", $text);
        // 移除连续的空格
        $text = preg_replace("/ +/", " ", $text);
        return trim($text);
    }
}
// 使用示例
try {
    $extractor = new WordTextExtractor();
    $text = $extractor->extract('document.docx');
    echo $text;
    // 保存到文件
    file_put_contents('extracted_text.txt', $text);
} catch (Exception $e) {
    echo "错误: " . $e->getMessage();
}

性能优化建议

  1. 缓存结果:如果多次提取相同文档,缓存提取结果
  2. 批量处理:处理大量文档时使用批处理
  3. 内存管理:大型文档注意内存使用
// 批量处理示例
function batchExtract($files) {
    $results = [];
    foreach ($files as $file) {
        $cacheKey = md5_file($file);
        $cacheFile = "cache/{$cacheKey}.txt";
        if (file_exists($cacheFile)) {
            $results[$file] = file_get_contents($cacheFile);
        } else {
            $extractor = new WordTextExtractor();
            $text = $extractor->extract($file);
            file_put_contents($cacheFile, $text);
            $results[$file] = $text;
        }
    }
    return $results;
}
  • 推荐方法:使用 PHPWord 库,功能完整,易于维护
  • 简单方案:直接解析 ZIP + XML
  • 复杂文档:需要处理表格、列表等特殊元素

选择哪种方法取决于你的具体需求:文档复杂度、性能要求、是否需要保留格式信息等。

抱歉,评论功能暂时关闭!