1. 首先确定使用phpword是可以读取word文档中表格里面的数据, 使用的phpword版本0.17.0
composer require "phpoffice/phpword"
2.关键词及包含原理 (这里只做简单概述)
本人做博文喜欢直接贴代码,直接用。可这个不太行啊,因为输入不统一,word格式样式太多,输出也不统一,有的要输出数据,有的要输出word或者html,所以这里就追一下原理(可能不严谨但是便于理解)
关键词
section(部分) : phpword中将word文档分为若干个section(部分)
element(元素) : 每个section包含若干个element(元素)、文本、图片,元素分为文本元素、表格元素、其他(未涉及不做讨论)
textRun(文本元素) : 每个文本集合包含多个文本
text(文本) : 为字符或者图片
table(表格元素) : 每个表格元素包含多个行 row
row(行) : 每个行包含多个列 cell
cell(列) : 每个列包含多个textRun(文本元素) 这里没错,就是包含多个文本元素(表格元素也可以但是没人在word表格的某一个格里再来一个表格吧)
各个节点之间的关系图
3.代码实现(本地测试已通)
<?php /** * Created by PhpStorm. * User: parker * Date: 2020/10/18 * Time: 16:09 */ namespace common\services; class WordService extends BaseService { public static function importWord($info) { $word = self::getWord($info['path']); dd($word); } /** * 获取word文档内容 * @param string $path * @return array */
public static function getWord($path = '') { //加载word文档,使用phpword处理
$phpWord = \PhpOffice\PhpWord\IOFactory::load($path); return self::getNodeContent($phpWord); } /** * 根据word主节点获取分节点内容 * @param $word * @return array */
public static function getNodeContent($word) { $return = []; //分解部分
foreach ($word->getSections() as $section) { if ($section instanceof \PhpOffice\PhpWord\Element\Section) { //分解元素
foreach ($section->getElements() as $element) { //文本元素
if ($element instanceof \PhpOffice\PhpWord\Element\TextRun) { $text = ''; foreach ($element->getElements() as $ele) { $text .= self::getTextNode($ele); } $return[] = $text; } //表格元素
else if ($element instanceof \PhpOffice\PhpWord\Element\Table) { foreach ($element->getRows() as $ele) { $return[] = self::getTableNode($ele); } } } } } return $return; } /** * 获取文档节点内容 * @param $node * @return string */
public static function getTextNode($node) { $return = ''; //处理文本
if ($node instanceof \PhpOffice\PhpWord\Element\Text) { $return .= $node->getText(); } //处理图片
else if ($node instanceof \PhpOffice\PhpWord\Element\Image) { $return .= self::pic2text($node); } //处理文本元素
else if ($node instanceof \PhpOffice\PhpWord\Element\TextRun) { foreach ($node->getElements() as $ele) { $return .= self::getTextNode($ele); } } return $return; } /** * 获取表格节点内容 * @param $node * @return string */
public static function getTableNode($node) { $return = ''; //处理行
if ($node instanceof \PhpOffice\PhpWord\Element\Row) { foreach ($node->getCells() as $ele) { $return .= self::getTableNode($ele); } } //处理列
else if ($node instanceof \PhpOffice\PhpWord\Element\Cell) { foreach ($node->getElements() as $ele) { $return .= self::getTextNode($ele); } } return $return; } /** * 处理word文档中base64格式图片 * @param $node * @return string */
public static function pic2text($node) { //获取图片编码
$imageData = $node->getImageStringData(true); //添加图片html显示标头
$imageData = 'data:' . $node->getImageType() . ';base64,' . $imageData; $return = '<img src="'.$imageData.'">'; return $return; } /** * 处理word文档中base64格式图片 * @param $node * @return string */
public static function pic2file($node) { //图片地址(一般为word文档地址+在word中的锚点位置)
$imageSrc = 'images/' . md5($node->getSource()) . '.' . $node->getImageExtension(); $imageData = $node->getImageStringData(true); //将图片保存在本地
file_put_contents($imageSrc, base64_decode($imageData)); return $imageSrc; } /** * 将word转化为html(转换存储html文件后展示) * @param $path * @throws \PhpOffice\PhpWord\Exception\Exception */
public static function word2html($path) { $phpWord = FileImportService::getOne($path); //转为html处理
$xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, "HTML"); $path = pathinfo($path); $fileName = $path['dirname'] . '/' . $path['filename'] . '.html'; $xmlWriter->save($fileName); $html = file_get_contents($fileName); echo $html; die; } }
参考文献
https://github.com/PHPOffice/PHPWord