自学内容网 自学内容网

国产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文档


原文地址:https://blog.csdn.net/wqqqianqian/article/details/145175475

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!