phpWord使用模板填充数据:包含表格及嵌套表格(多个表格/循环表格)

news2024/10/2 14:24:14

参考文档
模板处理

基础使用

安装过程省略,首先加载模板:
$templateProcessor = new TemplateProcessor(ROOT_PATH . 'uploads/template/自动生成模板.docx');

完整保存流程

首先,要进行测试,起码能够写一个完整的demo,以下是我测试时用的demo

        $templateProcessor = new TemplateProcessor(ROOT_PATH . 'public/static/自动生成模板.docx');
        (new \app\index\model\MyUse())->fillIpAndAddress($templateProcessor); // 这一行内部就是对word进行填充,所有测试代码都可以写在这里
        $filename = "test.doc";
        $templateProcessor->saveAs($filename); //另存为新word文档,根据模板和变量生成了新的文档

        $file = fopen($filename, "rb");//以只读和二进制模式打开文件
        Header("Content-type: application/octet-stream"); //告诉浏览器这是一个文件流格式的文件
        Header("Accept-Ranges: bytes");  //请求范围的度量单位
        Header("Accept-Length: " . filesize($filename)); //Content-Length是指定包含于请求或响应中数据的字节长度
        //用来告诉浏览器,文件是可以当做附件被下载,下载后的文件名称为$file_name该变量的值。
        Header("Content-Disposition: attachment; filename=$filename");
        echo fread($file, filesize($filename));   //读取文件内容并直接输出到浏览器
        fclose($file);
        exit ();

最基础的替换

模板加载好后,一般的数据,只需要在模板中设置变量名即可替换,如:
在这里插入图片描述
就相当于一个萝卜一个坑,xxx xxx ${firstname},使用时$templateProcessor->setValue('firstname', 'John');即可,非常简单

表格数据替换

首先是保留表头的数据替换:假设无表数据,保留表头,但是数据为空

姓名年龄
${name}${age}

若无数据,保留表头,但是数据为空

其实只需要计算数量,设置数量为0即可:

$templateProcessor->cloneRow('terminalNumber',0);

若有数据,填充

首先是计算数据量,然后按照数据量填充:

$count = count($userInfo);
$templateProcessor->cloneRow('name',$count);
if (is_array($userInfo) && count($userInfo) > 0) {
    if (!empty($userInfo)) {
        foreach ($userInfoas $key => $value) {
            $id = $key + 1;
            $templateProcessor->setValue("name#${id}", $value["name"]);
            $templateProcessor->setValue("age#${id}", $value["age"]);
        }
    }
}

循环表格替换

表格替换比较简单,即使是这种类型的表格,也只是往空格里填充数据而已,cloneRow依旧很容易做到

用户id用户信息
${userId} ${userName}
${userAddress}
依然是```$templateProcessor->cloneRow('userId', $count);```

但实际需求中,很可能有多个表,如根据查询的用户结果生成多个用户表数据,其中每个用户表数据包含这个用户所选的课程(即不唯一),这样的表结构设计在官方文档中没有找到。
首先确定要用克隆块,

${USER_CLASS}

用户的id为:${userId}

所选课程课程类型
${class${key}} ${type${key}}

${/USER_CLASS}

按照以上模式将word中需要生成多个表格的地方做好标记,稍微解释下为什么要这么做:
(1)使用克隆块,可以根据自己需要生成多个数据,这些数据包含表格,以及表格的额外信息
(2) ${class${key}} 这种方式来作为表中的key,是因为会生成多个表格,如果不再嵌套一个唯一key,那么最终数据每个表都会是一样的
代码如下:

foreach ($userClass as $key => $value) {
    $id = $key +1;
    $replacements[$id] = ["userId" => $value, "key" => $id];
  	$classRet = [];// 作用是拼凑最终的二维数组
    if (!empty($userClassInfo)) {
        foreach ($userClassInfo as $classKey => $class) {
            $addressCount++;
            $classRet[$key][$classKey ] = [
                "class" => $class["class"],
                "type" => $class["type"],
            ];
        }
    } else {
        $templateProcessor->setValue('userId', " ");
    }
}

实际上,就是构造一个二维数组:

{
    "101":[
        {
            "1":{
                "class":"数学",
                "type":"normal"
            },
            "2":{
                "class":"语文",
                "type":"normal"
            }
        }
    ],
    "102":[
        {
            "1":{
                "class":"数学",
                "type":"normal"
            },
            "2":{
                "class":"语文",
                "type":"normal"
            }
        }
    ]
}

这个数组需要包含两层的id,然后就是填充数据:

if (!empty($classRet)) {
                foreach ($classRetas $key => $value) {
                    $id = $key + 1;
                    $templateProcessor->cloneRow("class" . $id, $locationCount);
                    foreach ($value as $ipKey => $ipValue) {
                        $ipId = $ipKey + 1;
                        $templateProcessor->setValue("class${id}#${ipId}", $ipValue["class"]);
                        $templateProcessor->setValue("type${id}#${ipId}", $ipValue["type"]);
                    }
                }
            }

这样就可以填充了。
注意:
(1)我写的示例都是从我自己的代码修改而来,改后没有测试,主要是表达原理
(2)如果不要代码块,deleteBlock可能不生效,我是用的cloneBlock,数量设置为0,cloneRow设置空数据同理,如果不设置,当无数据时可能变量名会保留在最终生成的word中

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/544576.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

实验三---面向对象分析与设计——UML用例图与活动图

一、实验目的: 掌握面向对象分析中用例建模的基本思想,学会识别参与者和用例,掌握UML用例图的绘制方法,学会编写用例说明;了解活动图的作用和组成元素,掌握UML活动图的绘制方法,学会使用活动图来…

秒懂算法 | KMP算法(Java描述)

Knuth-Morris-Pratt 算法(简称 KMP)是由高德纳(Donald Ervin Knuth)和沃恩普拉特在1974年构思,同年詹姆斯H莫里斯也独立地设计出该算法,最终三人于1977年联合发表。该算法较Brute-Force算法有较大改进&…

门电路OD门

漏极开路输出的门电路(OD门) 为了满足输出电平的变换,输出大负载电流,以及实现“线与”功能,将CMOS门电路的输出级做成漏极开路的形式,称为漏极开路输出的门电路,简称OD(Open&#x…

【JVM】1. JVM与Java体系结构

文章目录 1.1. 前言🍉1.2. 参考书目🍉1.3. Java及JVM简介🍉1.4. Java发展的重大事件🍉1.5. 虚拟机与Java虚拟机🍉1.6. JVM的整体结构🍉1.7. Java代码执行流程🍉1.8. JVM的架构模型🍉…

4. QT中的鼠标键盘事件 --- 鼠标拖拽案例

1. 说明 在QT的控件或者窗口当中,如果对于当前鼠标或者键盘的功能需要自己定义,可以重写父类当中对应虚函数,主要包括以下几个: //键盘按键按下 virtual void keyPressEvent(QKeyEvent *event); //键盘按键抬起 virtual void ke…

为什么C++这么复杂还不被淘汰?

C是一门广泛使用的编程语言,主要用于系统和应用程序的开发。尽管C具有一些复杂的语法和概念,但它仍然是编程界的重量级选手,在编程语言排行榜中一直位居前列。为什么C这么复杂还不被淘汰呢? C有以下优势 1、C具有高性能 C是一门编…

unity进阶学习笔记:photonServer测试

photonServer是由photon发布的一个网络框架,其封装了UDP和TCP通信机制让用户可以直接调用API实现网络游戏通信 1 photonServer下载安装 进入Photon官网的SDK选项,选择下载Server。目前Server版本已经更新到v5,这里我为了和教程保持一致下载…

Unittest接口测试生成报告和日志方法

HTML报告 直接把HTMLTestRunner.py放入工程目录即可报告脚本封装 #HTNL格式报告now datetime.datetime.now().strftime(%Y-%m-%d_%H_%M_%S)htmlreport reportpath "/" now r"result.html"print("测试报告生成地址:%s"% htmlre…

Revit干货 | 系统族、内建族、可载入族一次性搞清楚!

对于使用人数较多的revit软件,其中的许多概念与我们常用的CAD完全不同,以至于让许多工程师觉得revit软件有点高深莫测,不可琢磨,从而有了抗拒心理。 Revit软件中的重要概念: “族”是revit软件中的很重要也很基本的概念…

程序的各种段以及堆栈相关问题

C中一般有三种变量: 局部变量全局变量静态变量 C中一般有五个内存段: 代码段 也叫文本段,包含frequently executed code通常是只读的(未了避免程序被错误改写)代码段是不包含程序变量(如局部变量、全局变…

【数据结构】带头双向链表,真正的六边形战士

文章目录 概要整体架构流程小结 概要 *数据结构中的链表在实际开发中应用非常广泛,但写一个链表并不是一件简单的事情。链表有八种结构,对于刚入门的新手来说,往往会先经历单链表的折磨。 而今天我要讲的带头双向链表非常适合新手学习&#…

C++6.类和对象(下)

1.友元函数,一般现在类的最上面。 2.函数的参数中,如果不改变,尽量加上const修饰。 3.对于自定义类型,使用运算符进行操作基本上都要用运算符重载,但是有些运算符重载会默认自动生成。 4.初始化列表,是成…

【wpf】列表类,用相对源时,如何绑定到子项

前言 在之前的一篇文章 :《【wpf】深度解析,Binding是如何寻找数据源的》https://blog.csdn.net/songhuangong123/article/details/126195727#:~:text%E3%80%90wpf%E3%80%91%E6%B7%B1%E5%BA%A6%E8%A7%A3%E6%9E%90%EF%BC%8CBinding%E6%98%AF%E5%A6%82%E4…

读书|林曦:她把自己的生活,过成了无用但丰盈的美学

时代在以加速度的方式变化,让人难以从容。而当我们陷于横向的比较系统,权衡着卷、躺、润时,也有人在探寻另一条纵向的路——向古人学习,以传统美学关照和滋养当下生活。      立夏之际,水墨画家林曦的新作《无用之…

33岁跳槽无路,濒临绝望之际受贵人指点,成功上岸阿里(测试岗)

写在前面 马上过34岁生日了,和大家聊聊最近的情况,半年前还在迷茫该学什么,怎样才能走出现在的困境,半年后已经成功上岸阿里,感谢在这期间帮助我的每一个人 开始 30多岁工作的时候总是有种力不从心的感觉&#xff0…

网络安全工程师需要考什么证吗?

目前网络安全行业,国内都有哪些证书可以考。 一、CISP-PTE (国家注册渗透测试工程师) CISP-PTE即注册信息安全渗透测试工程师,该证书由中国信息安全测评中心颁发,证书是国内唯一认可的渗透测试认证,专业性…

AIOps社区低代码项目火热报名中|中科院开源之夏2023,万元现金等你来拿!

活动介绍 开源之夏是由中科院软件所“开源软件供应链点亮计划”发起并长期支持的一项暑期开源活动,旨在鼓励在校学生积极参与开源软件的开发维护,培养和发掘更多优秀的开发者,促进优秀开源软件社区的蓬勃发展,助力开源软件供应链…

告别Excel,免费大数据分析与可视化工具,让你的论文图表“高大上”

数据分析工具很多,可以分为表格、数据库、BI工具、编程等四大工具。每个大类又有很多的工具,例如表格包括Excel、WPS、Google Sheets、Airtable等。编程工具包括Python和R。 搞科研几年了,笔者一直都是在使用Excel做数据分析和可视化&#xf…

Go语言中sync.Map、sync.Pool和Context的用法

目录 【sync.Map】 实现线程安全的 map 类型 使用 sync.Map 实现并发读写的map 【sync.Pool】 使用 带缓冲channel 实现对象池 使用 sync.Pool 创建临时对象池 【Context 上下文】 Context应用:实现带超时功能的远程调用 Context应用:监控指令…

电脑找不到MSVCR120.dll怎么办/MSVCR120.dll是什么?

电脑提示找不到MSVCR120.dll怎么办?你是否也遇到这个问题,MSVCR120.dll是什么文件呢?小编今天就把MSVCR120.dll文件丢失的修复方法给大家。msvcr120.dll是Microsoft Visual C 的一部分,它是Windows操作系统中的一个动态链接库文件…