本文目录导读:

- 方法一:使用 PHPWord 库(推荐)
- 方法二:使用正则表达式提取.docx中的XML文本
- 方法三:使用系统命令(需服务器支持)
- 方法四:使用 phpdocx 库(商业版)
- 完整解决方案(推荐)
- 性能优化建议
在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 使用 antiword 或 catdoc
<?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();
}
性能优化建议
- 缓存结果:如果多次提取相同文档,缓存提取结果
- 批量处理:处理大量文档时使用批处理
- 内存管理:大型文档注意内存使用
// 批量处理示例
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
- 复杂文档:需要处理表格、列表等特殊元素
选择哪种方法取决于你的具体需求:文档复杂度、性能要求、是否需要保留格式信息等。