使用phpword獲取doc中的表格資料
阿新 • • 發佈:2020-10-13
1. 首先確定使用phpword是可以讀取word文件中表格里面的資料, 使用的phpword版本0.17.0
2.理解word文件內容的儲存邏輯規則(這裡只做簡單概述)
本人做博文喜歡直接貼程式碼,直接用。可這個不太行啊,因為輸入不統一,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;
}
}