当前位置: 首页 > news >正文

国产linux系统(银河麒麟,统信uos)使用 PageOffice 实现后台批量生成PDF文档

PageOffice 国产版 :支持信创系统,支持银河麒麟V10和统信UOS,支持X86(intel、兆芯、海光等)、ARM(飞腾、鲲鹏、麒麟等)、龙芯(LoogArch)芯片架构。

PageOffice 版本:6.4.1.1及以上版本

在实际项目开发中经常会遇到后台动态生成文档的需求,目前网上有一些针对此需求的方案,如果您想要了解这些方案的对比,请查看后台生成单个Word文档中的“方案对比”。

如果一次只生成一份文档,请参考后台生成单个PDF文档;如果想要一次批量生成很多PDF文档,比如批量生成入学通知书、毕业证书或者员工信息档案等,那就需要使用PageOffice提供的 js 内置函数CallFileMaker循环调用FileMaker生成文档的功能,实现批量生成文档的效果。FileMaker动态生成PDF文件的过程是:在客户端动态生成 Office 文档,并自动另存为PDF格式上传到服务器,但是不在客户端打开显示文档,看起来就好像是在服务器端直接生成的PDF文件。所以PageOffice提供的解决方案,只需两步:

  • 首先调用FileMakerCtrl对象和WordDocumentWriter对象实现动态填充Word模板生成正式的Word文件并自动另存为PDF,实现动态生成PDF文档。
  • 然后递归调用PageOffice提供的js函数CallFileMaker,循环执行上一步的动态生成PDF操作,实现批量动态生成PDF文档的功能。

下面就以“批量生成荣誉证书”的需求为例,介绍一下如何使用FileMaker批量生成PDF文档的功能。

  1. 需求效果:用户在页面上勾选要生成荣誉证书的公司名,然后点击批量生成的按钮,就可以把各个公司的信息动态填充到荣誉证书的Word模板中,为每个公司生成一份荣誉证书的PDF文件。
  2. 荣誉证书模板如下图所示,为了简单起见,模板中只使用了公司名称来代表公司的所有信息,所以只用了一个数据区域“PO_company”来标记公司名称的位置。
    在这里插入图片描述
  3. 为了简单起见,下面介绍一下批量生成两份荣誉证书的过程。比如用户勾选了公司列表的前两个公司后,点击批量生成PDF的按钮,如下图所示。
    在这里插入图片描述
  4. 点击按钮后,重复调用把公司信息动态填充到Word模板中生成荣誉证书的后台代码(比如:/FileMaker),直到所有的荣誉证书文件都生成完毕。具体实现请参考下面的前端代码。如下图所示的两份荣誉证书,就是在服务器端文件夹下批量生成的两份PDF文件:maker1.pdf、maker2.pdf。
    在这里插入图片描述

FileMakerCtrl 和 PageOfficeCtrl 的区别 FileMakerCtrl 本质上就是一个没有界面的
PageOfficeCtrl,也是调用客户端 Office
程序处理文件的,FileMakerCtrl和PageOfficeCtrl都可以实现对文档进行动态填充、动态转 PDF 等功能,唯一的区别就是
FileMakerCtrl 在线打开填充和转换文档的时候,Web页面不会打开显示文档内容,而 PageOfficeCtrl
会弹出窗口打开显示文档内容。

后端代码

  1. 在后端编写代码实现文档动态填充,比如/FileMaker中关键代码如下:
String[] companyArr = {" ", "微软(中国)有限公司", "IBM(中国)服务有限公司", "亚马逊贸易有限公司", "脸书科技有限公司", "谷歌网络有限公司","英伟达技术有限公司","台积电科技有限责任公司", "沃尔玛股份有限公司"};
int id = Integer.parseInt(request.getParameter("id"));
FileMakerCtrl fmCtrl = new FileMakerCtrl(request);
WordDocumentWriter doc = new WordDocumentWriter();
//给数据区域赋值,即把数据填充到模板中相应的位置
doc.openDataRegion("PO_company").setValue(companyArr[id]);
fmCtrl.setWriter(doc);
fmCtrl.fillDocumentAsPDF("doc/template.doc", DocumentOpenType.Word, "a.pdf");
out.print(fmCtrl.getHtml());
  1. 在SaveFilePage属性指向的地址接口中,创建FileSaver对象处理文件的保存工作。
String id = request.getParameter("id");
FileSaver fs = new FileSaver(request, response);
String fileName = "maker" + id + fs.getFileExtName();
fs.saveToFile(request.getSession().getServletContext().getRealPath("FileMaker/doc") + "/" + fileName);
fs.setCustomSaveResult("{\"msg\":\"ok\"}");//用于给前端页面返回数据
fs.close();

前端代码

编写前端网页代码,通过CallFileMaker循环调用FileMaker生成文档的功能,实现批量生成PDF文件的效果。

<script setup>
import request from '@/utils/request';
import { ref, onMounted } from 'vue'
import { filemakerctrl } from 'js-pageoffice'const titleText = ref('');
const ids = [];
const buttonDisabled = ref(false);
const progressBar1 = ref(null);
const progressBar2 = ref(null);onMounted(async () => {try {const response = await request({url: '/index',method: 'get',});titleText.value = response;} catch (error) {console.error('Failed to fetch title:', error);}
})function ConvertFiles() {var checkboxes = document.getElementsByName("company");for (var i = 0; i < checkboxes.length; i++) {if (checkboxes[i].checked) {// 如果checkbox被选中ids.push(checkboxes[i].value);}}if (0 == ids.length) {alert("请至少选择一个公司");return;}buttonDisabled.value = true;ConvertFile(ids, 0);
}
function ConvertFile(idArr, index) {// 设置用于保存文件的服务器端controller地址,该地址需从"/"开始,指向服务器端根目录/** 如果想要给SaveFilePage传递多个参数,建议使用new URLSearchParams方式,例如:
* let saveFileUrl = "/FileMaker/save";
* let paramValue = new URLSearchParams({id:1,name:"张三"});
* filemakerctrl.SaveFilePage = `${saveFileUrl}?${paramValue.toString()}`;
*/filemakerctrl.SaveFilePage = "/FileMaker/save?id=" + idArr[index];filemakerctrl.CallFileMaker({// url:指向服务器端FileMakerCtrl打开文件的controller地址,该地址需从"/"开始,指向服务器端根目录  url: "/FileMaker/FileMaker?id=" + idArr[index],success: (res) => {//res:获取服务器端fs.setCustomSaveResult设置的保存结果console.log(res);console.log("completed successfully.");setProgress1(100);index++;setProgress2(index, idArr.length);if (index < idArr.length) {ConvertFile(idArr, index);}},progress: (pos) => {console.log("running " + pos + "%");setProgress1(pos);},error: (msg) => {console.log("error occurred: " + msg);},});
}
function setProgress1(percent) {progressBar1.value.style.width = percent + "%";progressBar1.value.innerText = percent + "%";
}
function setProgress2(index, count) {progressBar2.value.style.width = Math.round((index / count) * 100) + "%";progressBar2.value.innerText = index + "/" + count;
}
</script><template><div class="Word"><div style="text-align: center"><h3>演示:填充数据到模板中批量生成PDF文件</h3><div style="width: 600px; margin: 0 auto; font-size: 14px"><p style="text-align: left">演示内容:<br />&nbsp;&nbsp;&nbsp;&nbsp;本示例演示了批量生成荣誉证书的效果。选择需要生成荣誉证书的公司,然后点击“批量生成PDF文件”按钮,就可以把各个公司名动态填充到荣誉证书模板“template.doc”中,为每个公司生成一份荣誉证书文件。</p><p style="text-align: left">操作说明:<br />1. 勾选下面的公司名称;<br />2. 点击“批量生成PDF文件”按钮;<br />3. 生成完毕后,即可在“FileMaker/doc”目录下看到批量生成的PDF文件。<br /></p></div><hr /><ul class="company-list"><li><label>1<input name="company" value="1" type="checkbox" />微软(中国)有限公司</label></li><li><label>2<input name="company" value="2" type="checkbox" />IBM(中国)服务有限公司</label></li><li><label>3<input name="company" value="3" type="checkbox" />亚马逊贸易有限公司</label></li><li><label>4<input name="company" value="4" type="checkbox" /> 脸书科技有限公司</label></li><li><label>5<input name="company" value="5" type="checkbox" /> 谷歌网络有限公司</label></li><li><label>6<input name="company" value="6" type="checkbox" />英伟达技术有限公司</label></li><li><label>7<input name="company" value="7" type="checkbox" />台积电科技有限责任公司</label></li><li><label>8<input name="company" value="8" type="checkbox" />沃尔玛股份有限公司</label></li></ul><input id="Button1" type="button" :disabled="buttonDisabled" value="批量生成PDF文件" @click="ConvertFiles()" /><br /><div id="progressDiv">单文件进度:<div class="progressBarContainer"><div id="progressBar1" ref="progressBar1" class="progressBar"></div></div>整体进度:<div class="progressBarContainer"><div id="progressBar2" ref="progressBar2" class="progressBar"></div></div></div></div></div>
</template><style scoped>
h3 {display: block;font-size: 1.17em;margin-block-start: 1em;margin-block-end: 1em;margin-inline-start: 0px;margin-inline-end: 0px;font-weight: bold;
}
h2 {display: block;font-size: 1.5em;margin-block-start: 0.83em;margin-block-end: 0.83em;margin-inline-start: 0px;margin-inline-end: 0px;font-weight: bold;
}
.progressBarContainer {width: 100%;background-color: #eee;border-radius: 5px;padding: 3px;box-shadow: 2px 2px 3px 3px #ccc inset;
}
.progressBar {height: 20px;width: 0%;background-color: #1a73e8;border-radius: 5px;text-align: center;line-height: 20px;color: white;
}
#progressDiv {width: 400px;margin: 10px auto;text-align: left;font-size: 14px;border: solid 1px #1a73e8;padding: 10px 20px;color: #1a73e8;
}
.company-list {list-style-type: none;padding: 0;margin: 0 auto;width: 400px;
}
.company-list li {display: flex;justify-content: space-between;align-items: center;margin-bottom: 10px;
}
.company-list label {display: block;font-weight: bold;margin-bottom: 5px;
}
.company-list input[type="checkbox"] {margin-right: 5px;
}
</style>

参考链接:后台批量生成PDF文档

相关文章:

国产linux系统(银河麒麟,统信uos)使用 PageOffice 实现后台批量生成PDF文档

PageOffice 国产版 &#xff1a;支持信创系统&#xff0c;支持银河麒麟V10和统信UOS&#xff0c;支持X86&#xff08;intel、兆芯、海光等&#xff09;、ARM&#xff08;飞腾、鲲鹏、麒麟等&#xff09;、龙芯&#xff08;LoogArch&#xff09;芯片架构。 PageOffice 版本&…...

Python 扫描枪读取发票数据导入Excel

财务需要一个扫描枪扫描发票文件&#xff0c;并将主要信息录入Excel 的功能。 文件中sheet表的列名称&#xff0c;依次为&#xff1a;发票编号、发票编码、日期、金额、工号、扫描日期。 扫描的时候&#xff0c;Excel 文件需要关闭&#xff0c;否则会报错。 import openpyxl …...

电源自动测试系统中的ate定制化包含哪些内容?

1. 测试项目和指标 基础测试项目&#xff1a;虽然大多数电源模块的基础测试项目&#xff08;如输入输出电压、电流、效率等&#xff09;已经包含在测试系统中&#xff0c;但针对特殊或小众的测试项目&#xff0c;如VPX电源测试时的通讯验证&#xff0c;可以根据客户需求进行定…...

人工智能-机器学习之多分类分析(项目实战二-鸢尾花的多分类分析)

Softmax回归听名字&#xff0c;依然好像是做回归任务的算法&#xff0c;但其实它是去做多分类任务的算法。 篮球比赛胜负是二分类&#xff0c;足球比赛胜平负就是多分类 识别手写数字0和1是二分类&#xff0c;识别手写数字0-9就是多分类 Softmax回归算法是一种用于多分类问题…...

多包单仓库(monorepo)实现形式

目录 背景 需求和方案 从0开始搭建一个Monorepo项目 创建 配置全局公共样式 配置全局公共组件 方式1:不需要独立发布的组件包,只在当前项目的子项目中使用 方式2:需要独立发布和版本维护的包 子项目的独立构建和部署 总结 Monorepo优势 便于代码维护、管理 支持…...

Java冒泡排序算法之:变种版

什么是冒泡排序算法&#xff1f; 冒泡排序是一种简单的排序算法&#xff0c;通过多次遍历待排序的数组&#xff0c;逐步将最大的&#xff08;或最小的&#xff09;元素“冒泡”到数组的一端。它以其操作过程类似气泡从水底冒至水面而得名。 冒泡排序的工作原理 比较相邻元素&…...

AAPM:基于大型语言模型代理的资产定价模型,夏普比率提高9.6%

“AAPM: Large Language Model Agent-based Asset Pricing Models” 论文地址&#xff1a;https://arxiv.org/pdf/2409.17266v1 Github地址&#xff1a;https://github.com/chengjunyan1/AAPM 摘要 这篇文章介绍了一种利用LLM代理的资产定价模型&#xff08;AAPM&#xff09;…...

Spring常见知识

1、什么是spring的ioc&#xff1f; 其实就是控制反转&#xff0c;提前定义了一个bean&#xff0c;到时候使用的时候直接autowire就可以了。目的是减低计算机代码之间的耦合度。 创建三个文件&#xff0c;分别是Bean的定义、Bean的使用、Bean的配置。 IOC通过将对象创建和管理…...

计算机网络的五层协议

计算机网络的五层协议 ‌计算机网络的五层协议模型包括物理层、数据链路层、网络层、传输层和应用层&#xff0c;每一层都有其特定的功能和相关的协议。‌‌1 ‌物理层‌&#xff1a;负责传输原始的比特流&#xff0c;通过线路&#xff08;有线或无线&#xff09;将数据转换为…...

Bluetooth LE Audio - 蓝牙无线音频新应用 (上)

SIG联盟&#xff08;Bluetooth Special Interest Group&#xff09;自2020年开始推广新的LE Audio&#xff0c;在穿戴式装置掀起一股热潮&#xff0c;各个品牌商、制造商、第三方软件商都积极的寻找新的LE Audio规格究竟能提供什么样的新应用。究竟LE Audio如何改变你我的生活、…...

如何快速准备数学建模?

前言 大家好,我是fanstuck。数学建模不仅是解决复杂现实问题的一种有效工具,也是许多学科和行业中的关键技能。从工程、经济到生物、环境等多个领域,数学建模为我们提供了将实际问题转化为数学形式,并利用数学理论和方法进行求解的强大能力。然而,对于许多初学者而言,如…...

如何在linux系统上完成定时开机和更新github端口的任务

任务背景 1.即使打开代理&#xff0c;有的时候github去clone比较大的文件时也会出问题。这时需要每小时更新一次github的host端口&#xff1b; 2.马上要放假&#xff0c;想远程登录在学校的台式电脑&#xff0c;但学校内网又不太好穿透。退而求其次&#xff0c;选择定时启动电…...

Jupyter notebook中运行dos指令运行方法

Jupyter notebook中运行dos指令运行方法 目录 Jupyter notebook中运行dos指令运行方法一、DOS(磁盘操作系统&#xff09;指令介绍1.1 DOS介绍1.2 DOS指令1.2.1 DIR - 显示当前目录下的文件和子目录列表。1.2.2 CD 或 CHDIR - 改变当前目录1.2.3 使用 CD .. 可以返回上一级目录1…...

探索 Linux:(一)介绍Linux历史与Linux环境配置

探索 Linux:&#xff08;一&#xff09;介绍Linux历史与Linux环境配置 一. 计算机与操作系统的历史1.1计算机的历史1.2操作系统的历史 二、Unix 操作系统的历史三、Linux 与安卓的关系3.1Linux 与安卓的关系3.2安卓的历史 四、Linux 简单介绍五、Linux 环境安装5.1 虚拟机5.2 直…...

前端【2】html添加样式、CSS选择器

一、为html添加样式的三种方法 1、内部样式 2、外部样式 3、行内样式 二、css的使用--css选择器 1、css基本选择器 元素选择器 属性选择器 id选择器 class/类选择器 通配符选择器 2、群组选择器-多方面筛选 3、关系选择器 后代选择器【包含选择器】 子元素选择器…...

Yolov8 目标检测剪枝学习记录

最近在进行YOLOv8系列的轻量化&#xff0c;目前在网络结构方面的优化已经接近极限了&#xff0c;所以想要学习一下模型剪枝是否能够进一步优化模型的性能 这里主要参考了torch-pruning的基本使用&#xff0c;v8模型剪枝&#xff0c;Jetson nano部署剪枝YOLOv8 下面只是记录一个…...

LeDeCo:AI自动化排版、设计、美化海报

1.简介 平面设计是一门艺术学科&#xff0c;致力于创造吸引注意力和有效传达信息的视觉内容。今天&#xff0c;创造视觉上吸引人的设计完全依赖于具有艺术创造力和技术专长的人类设计师&#xff0c;他们巧妙地整合多模态图形元素&#xff0c;这是一个复杂而耗时的过程&#xf…...

Flink CDC解决数据库同步,异常情况下增量、全量问题

Flink 1.11 引入了 Flink SQL CDC&#xff0c;CDC 能给我们数据和业务间能带来什么变化&#xff1f;本文由 Apache Flink PMC&#xff0c;阿里巴巴技术专家伍翀 (云邪&#xff09;分享&#xff0c;内容将从传统的数据同步方案&#xff0c;基于 Flink CDC 同步的解决方案以及更多…...

01、flink的原理和安装部署

flink中主要有两个进程&#xff0c;分别是JobMManager和TaskManager&#xff0c;当然了根据flink的部署和运行环境不同&#xff0c;会有一些不同&#xff0c;但是主要的功能是类似的&#xff0c;下面我会讲下聊下&#xff0c;公司用的多的部署方式&#xff0c;基于yarn集群的部…...

美图脱掉“复古外衣”,在AI浪潮中蜕变

"人工智能就像电力一样&#xff0c;如果你的竞争对手正在使用它&#xff0c;你也需要使用它&#xff0c;否则你就会失去竞争力"&#xff0c;斯坦福大学教授和谷歌前首席科学家安德鲁恩格尔曾这样说到。 而近日拉开序幕的消费电子风向标——科技贸易展国际消费电子展…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录

ASP.NET Core 是一个跨平台的开源框架&#xff0c;用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录&#xff0c;以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...

MODBUS TCP转CANopen 技术赋能高效协同作业

在现代工业自动化领域&#xff0c;MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步&#xff0c;这两种通讯协议也正在被逐步融合&#xff0c;形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...

Kafka入门-生产者

生产者 生产者发送流程&#xff1a; 延迟时间为0ms时&#xff0c;也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于&#xff1a;异步发送不需要等待结果&#xff0c;同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...

【Veristand】Veristand环境安装教程-Linux RT / Windows

首先声明&#xff0c;此教程是针对Simulink编译模型并导入Veristand中编写的&#xff0c;同时需要注意的是老用户编译可能用的是Veristand Model Framework&#xff0c;那个是历史版本&#xff0c;且NI不会再维护&#xff0c;新版本编译支持为VeriStand Model Generation Suppo…...

yaml读取写入常见错误 (‘cannot represent an object‘, 117)

错误一&#xff1a;yaml.representer.RepresenterError: (‘cannot represent an object’, 117) 出现这个问题一直没找到原因&#xff0c;后面把yaml.safe_dump直接替换成yaml.dump&#xff0c;确实能保存&#xff0c;但出现乱码&#xff1a; 放弃yaml.dump&#xff0c;又切…...

前端工具库lodash与lodash-es区别详解

lodash 和 lodash-es 是同一工具库的两个不同版本&#xff0c;核心功能完全一致&#xff0c;主要区别在于模块化格式和优化方式&#xff0c;适合不同的开发环境。以下是详细对比&#xff1a; 1. 模块化格式 lodash 使用 CommonJS 模块格式&#xff08;require/module.exports&a…...

python打卡day49@浙大疏锦行

知识点回顾&#xff1a; 通道注意力模块复习空间注意力模块CBAM的定义 作业&#xff1a;尝试对今天的模型检查参数数目&#xff0c;并用tensorboard查看训练过程 一、通道注意力模块复习 & CBAM实现 import torch import torch.nn as nnclass CBAM(nn.Module):def __init__…...

二维数组 行列混淆区分 js

二维数组定义 行 row&#xff1a;是“横着的一整行” 列 column&#xff1a;是“竖着的一整列” 在 JavaScript 里访问二维数组 grid[i][j] 表示 第i行第j列的元素 let grid [[1, 2, 3], // 第0行[4, 5, 6], // 第1行[7, 8, 9] // 第2行 ];// grid[i][j] 表示 第i行第j列的…...

window 显示驱动开发-如何查询视频处理功能(三)

​D3DDDICAPS_GETPROCAMPRANGE请求类型 UMD 返回指向 DXVADDI_VALUERANGE 结构的指针&#xff0c;该结构包含特定视频流上特定 ProcAmp 控件属性允许的值范围。 Direct3D 运行时在D3DDDIARG_GETCAPS的 pInfo 成员指向的变量中为特定视频流的 ProcAmp 控件属性指定DXVADDI_QUER…...

Caliper 配置文件解析:config.yaml 和 fisco-bcos.json 附加在caliper中执行不同的合约方法

Caliper 配置文件解析:config.yaml 和 fisco-bcos.json Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO…...