通過html的table生成world表格代碼
在thinkphp index 控制器中做的例子
不兼容樣式 只能簡單的生成表格
可能還有其他形式的表格不兼容(慎重使用)
namespace app\index\controller;
use PhpOffice\PhpWord\IOFactory;
use PhpOffice\PhpWord\PhpWord;
use think\Db;
class Index
{
public function index()
{
$phpWord = new PhpWord();
$section = $phpWord->addSection();
header("Content-type:text/html;charset=utf-8");
$phpWord->addTableStyle(
'myTable',
[
'borderSize' => '1',
'borderColor' => '000000',
]
);
$txt = array (
"表格1\n",
'<table><tr><td rowspan="4">1-1</td><td>1-2</td><td>1-3</td><td>1-4</td><td>1-5</td><td rowspan="4">1-6</td></tr><tr><td>2-2</td><td colspan="2" rowspan="2">2-3</td><td>2-4</td></tr><tr><td>3-2</td><td>3-5</td></tr><tr><td>4-2</td><td>4-3</td><td>4-4</td><td>4-5</td></tr></table>',
"表格2\n",
'<table><tr><td>1-1</td><td>1-2</td><td>1-3</td><td>1-4</td><td>1-5</td></tr><tr><td>2-1</td><td>2-2</td><td>2-3</td><td>2-4</td><td>2-5</td></tr><tr><td>3-1</td><td>3-2</td><td>3-3</td><td>3-4</td><td>3-5</td></tr><tr><td>4-1</td><td>4-2</td><td>4-3</td><td>4-4</td><td>4-5</td></tr></table>',
"表格3\n",
'<table><tr><td colspan="2" rowspan="2">1-1</td><td>1-3</td><td>1-4</td></tr><tr><td rowspan="2">2-3</td><td>2-4</td></tr><tr><td>3-1</td><td>3-2</td><td rowspan="2">3-4</td></tr><tr><td colspan="2">4-1</td><td>4-2</td></tr></table>',
"表格4\n",
'<table><tr><td rowspan="3" colspan="2">1-1</td><td colspan="3">1-3</td><td>1-6</td><td rowspan="3">1-7</td><td colspan="2" rowspan="5">1-8</td><td>1-9</td></tr><tr><td>2-3</td><td>2-4</td><td>2-5</td><td>2-6</td><td>2-9</td></tr><tr><td colspan="2">3-3</td><td colspan="2" rowspan="2">3-5</td><td rowspan="2">3-9</td></tr><tr><td>4-1</td><td>4-2</td><td>4-3</td><td>4-4</td><td>4-7</td></tr><tr><td colspan="2">5-1</td><td colspan="2">5-3</td><td colspan="2">5-5</td><td>5-7</td><td>5-9</td></tr></table>',
"表格5\n",
'<table><tr><td colspan="2">1-1</td><td>1-3</td><td colspan="3">1-4</td><td>1-7</td><td>1-8</td><td>1-9</td><td>1-10</td></tr><tr><td rowspan="3">2-1</td><td rowspan="2">2-2</td><td colspan="8">2-3</td></tr><tr><td rowspan="2">3-3</td><td rowspan="3">3-4</td><td>3-5</td><td>3-6</td><td rowspan="4">3-7</td><td>3-8</td><td colspan="2" rowspan="3">3-9</td></tr><tr><td rowspan="3">4-2</td><td rowspan="2" colspan="2">4-5</td><td>4-8</td></tr><tr><td>5-1</td><td>5-3</td><td>5-8</td></tr><tr><td>6-1</td><td>6-3</td><td>6-4</td><td>6-5</td><td>6-6</td><td>6-8</td><td>6-9</td><td>6-10</td></tr></table>'
);
for ($i=0;$i<count($txt);$i++)
{
if (preg_match('/<table[\s\S]*>/',$txt[$i]))
{
$this->createTable($section,$txt[$i]);
}else{
$section->addText($txt[$i]);
}
}
$objWriter = IOFactory::createWriter($phpWord,'Word2007');
$file = '測(cè)試文檔.docx';
header("Content-Description: File Transfer");
header('Content-Disposition: attachment; filename="' . $file . '"');
header('Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document');
header('Content-Transfer-Encoding: binary');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Expires: 0');
$objWriter->save('PHP://output');
}
/**
*
* 具體思路:
* 通過 rowspan 與 colspan 還原基本表格
* 記錄 rowspan 的每行坐標(biāo) 組合colspan 進(jìn)行 每次一行生成表格
*
* @param \PhpOffice\PhpWord\Element\Section $section
* @param string $strTable
*/
private function createTable($section,$strTable)
{
//查找所有的table標(biāo)簽
preg_match_all("/<table[\s\S]*>[\s\S]*<\/table>/U",$strTable,$tables);
for ($tableI=0;$tableI<count($tables[0]);$tableI++)
{
//設(shè)置table樣式
$table = $section->addTable('myTable');
//尋找行
preg_match_all("/<tr>[\s\S]*<\/tr>/U",$tables[0][$tableI],$tr);
//合并列的數(shù)據(jù)
$tableRowSpan = [];
for ($r = 0;$r < count($tr[0]);$r ++)
{
$table->addRow(); //增加一行
//尋找列
preg_match_all("/<td[\s\S]*>([\s\S]*)<\/td>/U",$tr[0][$r],$td);
//找出所有的colspan的數(shù)量 通過此數(shù)量可計(jì)算出一共有多少列
preg_match_all('/colspan="(\d{1,})"/U',$tr[0][$r],$colspanNumber);
//只取一次有多少列
if (!isset($tdTotal))
{
//td總數(shù)量 = 匹配到的數(shù)量 + colspan的總和 - colspan的總數(shù)
$tdTotal = count($td[0]) + array_sum($colspanNumber[1]) - count($colspanNumber[1]);
}
//將每一個(gè)rowspan記錄到數(shù)組中 如果同時(shí)含有 colspan 進(jìn)行特俗處理
$tdAddUp= 0;
for ($j=0;$j<$tdTotal;$j++){
//驗(yàn)證此處是否已經(jīng)記錄過 分為兩種情況 第一次出現(xiàn)rowspan時(shí)可以正確獲取到
//第二次 以后 由于上面有rowspan 則第一位的td并不是應(yīng)當(dāng)記錄的 坐標(biāo)
//如果曾經(jīng)已記錄過忽略就可以了
if (!isset($tableRowSpan[$j]))
{
//查看是否含有colspan屬性 并獲得 colspan 的 數(shù)量
$isColspan = preg_match('/colspan="(\d{1,})"/',$td[0][$tdAddUp],$colspanCount);
//驗(yàn)證是否含有 rowspan 屬性并獲得數(shù)量
if (preg_match('/rowspan="(\d{1,})"/',$td[0][$tdAddUp],$number))
{
//取出 rowspan 屬性的內(nèi)容
preg_match('/<td[\s\S]*>([\s\S]*)<\/td>/',$td[0][$tdAddUp],$value);
$tableRowSpan[$j] = [
'rowCount' => $number[1], //記錄rowspan的數(shù)量
'total' => $number[1], //記錄rowspan的總數(shù) 通過它可以驗(yàn)證是否為第一次添加
'colsCount' => isset($colspanCount[1])?$colspanCount[1]:0, //記錄colspan的數(shù)量 作為是否添加 列的條件
'value' => $value[1]
];
// 如果同時(shí)含有 rowspan 與 colspan 兩個(gè)屬性 則向后補(bǔ)位空數(shù)組,數(shù)量為colspan的值
if ($isColspan)
{
for ($colcI = 0; $colcI < $colspanCount[1] - 1;$colcI++){
$tableRowSpan[++$j] = [];
}
}
}else{
//只有colspan屬性 $j 的增量為 colspan 的值減1
if ($isColspan){
$j+=$colspanCount[1] - 1;
}
}
//每次檢查后 需要增加1
$tdAddUp++;
}
}
//所有有rowspan屬性的td已被記錄在 $tableRowSpan 變量中 所以在要在匹配到的 td中 刪除 鲜棠,否則會(huì)被重復(fù)添加
for ($delI = count($td[0]) - 1;$delI >= 0; $delI --)
{
$isRowSpan = preg_match('/rowspan="(\d{1,})"/U',$td[0][$delI]);
if ($isRowSpan){
array_splice($td[0],$delI,1);
array_splice($td[1],$delI,1);
}
}
//普通td的下標(biāo)記錄
$tdCount = 0;
//以變量$c為橫向坐標(biāo)系 也就是html中table的tr為一行 開始生成表格
for ($c=0;$c<$tdTotal;)
{
// $c的增量 由于存在colspan屬性的td $c 的增量不是 1 需要根據(jù)colspan的數(shù)量增加 默認(rèn)為 1
$addUp = 1;
//首選驗(yàn)證是否在 $tableRowSpan 記錄了此行td的 rowspan 的屬性
if (isset($tableRowSpan[$c]))
{
//由于 td 同時(shí) 含有 rowspan 與 colspan 屬性時(shí) 會(huì)在 $tableRowSpan 使用空數(shù)組進(jìn)行補(bǔ)位
//所以需要在驗(yàn)證是否為補(bǔ)位的數(shù)據(jù)
if (isset($tableRowSpan[$c]['rowCount']) && $tableRowSpan[$c]['rowCount'] > 0)
{
//記錄行數(shù)與總行數(shù) 不匹配則使用 continue 屬性 反之 則使用 restart
$vMerge = $tableRowSpan[$c]['rowCount'] == $tableRowSpan[$c]['total']?'restart':'continue';
//增加一個(gè)td并且設(shè)置屬性 如果 $vMerge 為 restart 說明是第一次添加 加入 td的值
//并將 colspan的屬性 加入其中
$table->addCell(2000,['vMerge' => $vMerge,'gridSpan' => $tableRowSpan[$c]['colsCount']])->addText($vMerge == 'restart'?$tableRowSpan[$c]['value']:'');
//每增加一個(gè)進(jìn)行減少操作
$tableRowSpan[$c]['rowCount']--;
//如果此列所有的 rowspan屬性增加完畢 則 將此記錄移除
if ($tableRowSpan[$c]['rowCount'] == 0) unset($tableRowSpan[$c]);
}else{
//如果為補(bǔ)位的數(shù)據(jù) 還需要驗(yàn)證前 一個(gè) rowspan屬性是否增加完畢 增加完畢則移除
if (empty($tableRowSpan[$c]) && !isset($tableRowSpan[$c - 1])) unset($tableRowSpan[$c]);
}
}else{//html中table中正常的 td 或只含有 colspan 的 td
//獲取td中包含的值
preg_match('/<td[\s\S]*>([\s\S]*)<\/td>/',$td[0][$tdCount],$tdValue);
$gridSpan = 0; //colspan的默認(rèn)值
//獲得td 中colspan的值
if (preg_match('/colspan="(\d{1,})"/',$td[0][$tdCount],$number))
{
//$addUp是$c 的增量并且他的默認(rèn)增量是 1
//$gridSpan 是 td 的行合并數(shù)量
//因此兩個(gè) 參數(shù)的值都以 $number[1] 的數(shù)量變化
$addUp = $gridSpan = $number[1];
}
//增加一個(gè)td 并且填入值
$table->addCell(2000,['gridSpan' => $gridSpan])->addText($tdValue[1]);
//由于已將含有 rowspan 屬性的td去除,此處每增加一個(gè)td 就需要增加 1
$tdCount++;
}
//累計(jì)行的增量
$c+=$addUp;
}
}
//表格結(jié)束后增加換行
$section->addText("\n");
}
}
}
原創(chuàng)文章,禁止任何形式的轉(zhuǎn)載