PHPWord 实现合并多个word文件(完结)

您所在的位置:网站首页 怎么合并两个word文档内容 PHPWord 实现合并多个word文件(完结)

PHPWord 实现合并多个word文件(完结)

2024-07-11 19:47| 来源: 网络整理| 查看: 265

PHPWord

本来想着当调包侠呢,结果翻了一遍文档,没有这种操作支持,阿这😂

GPT

不出意外的一顿胡扯,给👨‍🦳气的要中风啦

思路

word 也就是docx结尾的文件本质上就是xml字符串, 两个word文件合并其实就是把两个字符串拼接起来,你真是小天才呢👨‍🎤

具体步骤

原地址 【能打开的直接抄就完啦】

打不开的也别急,我给你搬运一份奥🤟

首先要拓展一下官方的类,为啥涅?里面的属性咱拿不到

class OpenTemplateProcessor extends \PhpOffice\PhpWord\TemplateProcessor { public function __construct($instance) { return parent::__construct($instance); } public function __get($key) { return $this->$key; } public function __set($key, $val) { return $this->$key = $val; } }

然后就可以愉快的拼接xml字符串啦,有一些xml的固定格式需要注意👍

$mainTemplateProcessor = new \common\helpers\OpenTemplateProcessor($filename); $innerTemplateProcessor = new \common\helpers\OpenTemplateProcessor($filename); // 拓展类就是为了拿到他的xml $innerXml = $innerTemplateProcessor->tempDocumentMainPart; $innerXml = preg_replace('/^[\s\S]*(.*).*/ ', '$1 ', $innerXml); // remove tag containing header, footer, images $innerXml = preg_replace('/.*/ ', ' ', $innerXml); // 把取出来的内容放进 结束符之前 $mainXml = $mainTemplateProcessor->tempDocumentMainPart; $mainXml = preg_replace('//', '' . $innerXml . ' ', $mainXml); $mainTemplateProcessor->tempDocumentMainPart = $mainXml; $mainTemplateProcessor->saveAs($folder . "1.docx"); 关于文件合并后图片显示重复的问题

因为之前拿相同的文件测试的并没有发现😅

word文件转成xml后的内容(以OpenTemplateProcessor这个类为例)

$this->tempDocumentRelations $this->tempDocumentMainPart ....太多了省略下 // 这个name // 还有这个r:embed

根据结构可以看出图片是怎么构成的 name 和 r:embed 其中r:embed的值就在 Relationships中,这样就标识了一个图片

看到这大概明白怎么回事了,因为不同word文件中的r:embed值可能是相同(大概率是),百度了一下word里的图片默认是按1,2这样递增的数 值标识。

按我们上面的操作,只拼接了w:body 里的字符 并忽略了文件2的 Relationships,所以文件2的图片指向了文件1的Relationships

思路弄明白就简单了,就是把Relationships 的图片也合并过来,然后r:embed的标识符要改,还有一点比较重要是图片资源也要写入到第一个word中去,光修改标识符是不够的,毕竟字符串合并图片都不存在

简单的示例:

$files = File::files(public_path("storage/we")); // 获取目录下的所有文件 $mainXml = ""; $mainTemplateProcessor = null; foreach ($files as $key=> $file) { if ($key != 0) { $innerTemplateProcessor = new Template($file->getRealPath()); $innerXml = $innerTemplateProcessor->tempDocumentMainPart; // 正则出所有的图片 preg_match_all('//',$innerTemplateProcessor->tempDocumentRelations['word/document.xml'],$res); // 把图片索引更改下,追加并写入 foreach ($res[0] as $k => $v) { $rid = "rId{$key}{$k}"; $innerXml = str_replace($res[1][$k],$rid,$innerXml); $extension = pathinfo($res[2][$k], PATHINFO_EXTENSION); $mediaName = "media/image{$rid}.{$extension}"; $relations = str_replace( [$res[1][$k],$res[2][$k]], [$rid,$mediaName], $v); if (!$mainTemplateProcessor->zipClass->addFromString('word/'.$mediaName,$innerTemplateProcessor->zipClass->getFromName('word/'.$res[2][$k]))){ throw new \Exception("add media fail"); } $tempData = $mainTemplateProcessor->tempDocumentRelations; $tempData['word/document.xml'] = str_replace('',$relations,$mainTemplateProcessor->tempDocumentRelations['word/document.xml']).''; $mainTemplateProcessor->tempDocumentRelations = $tempData; } $innerXml = preg_replace('/^[\s\S]*(.*).*/ ', '$1 ', $innerXml); $innerXml = preg_replace('/.*/ ', ' ', $innerXml); $mainXml= preg_replace('//', '' . $innerXml . ' ', $mainXml); } else { $mainTemplateProcessor = new Template($file->getRealPath()); $mainXml = $mainTemplateProcessor->tempDocumentMainPart; } } $mainTemplateProcessor->tempDocumentMainPart = $mainXml; $mainTemplateProcessor->saveAs(public_path("storage/3.docx"));


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3