Pageoffice6 实现后台批量生成Word文档

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

如果一次只生成一份文档,请参考后台生成单个Word文档;如果想要一次批量生成很多文档,那就需要使用PageOffice提供的 js 内置函数CallFileMaker循环调用FileMaker生成文档的功能,实现批量生成文档的效果,下面就以“批量生成荣誉证书”的需求为例,介绍一下如何使用FileMaker批量生成文档的功能。

  1. 需求效果:用户在页面上勾选要生成荣誉证书的公司名,然后点击批量生成的按钮,就可以把各个公司的信息动态填充到荣誉证书模板中,为每个公司生成一份荣誉证书文件。

  2. 荣誉证书模板如下图所示,为了简单起见,模板中只使用了公司名称来代表公司的所有信息,所以只用了一个数据区域“PO_company”来标记公司名称的位置。
    image

  3. 为了简单起见,下面介绍一下批量生成两份荣誉证书的过程。比如用户勾选了公司列表的前两个公司后,点击批量生成Word文件的按钮,如下图所示。
    image

  4. 点击按钮后,重复调用把公司信息动态填充到Word模板中生成荣誉证书的后台代码(比如:FileMaker.jsp),直到所有的荣誉证书文件都生成完毕。具体实现请参考下面的前端代码。如下图所示的两份荣誉证书,就是在服务器端文件夹下批量生成的两份Word文件:maker1.doc、maker2.doc。
    image

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

后端代码

  1. 在后端编写代码实现文档动态填充,比如FileMaker.jsp中关键代码如下:
String[] companyArr = {" ", "微软(中国)有限公司", "IBM(中国)服务有限公司", 
						"亚马逊贸易有限公司", "脸书科技有限公司", "谷歌网络有限公司",
						"英伟达技术有限公司","台积电科技有限责任公司", "沃尔玛股份有限公司"};
int id = Integer.parseInt(request.getParameter("id"));
FileMakerCtrl fmCtrl = new FileMakerCtrl(request);
WordDocument doc = new WordDocument();
//给数据区域赋值,即把数据填充到模板中相应的位置
doc.openDataRegion("PO_company").setValue(companyArr[id]);
fmCtrl.setSaveFilePage("SaveMaker.jsp?id=" + id);
fmCtrl.setWriter(doc);
fmCtrl.fillDocument("doc/template.doc", DocumentOpenType.Word);
  1. 在SaveFilePage属性指向的地址接口中(比如:SaveMaker.jsp),创建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.close();

前端代码

编写前端网页代码,实现批量生成文件的效果。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
    <title></title>
    <script type="text/javascript">
		var ids = [1,2]; //假设这就是用户勾选的两个公司的id
		
		function ConvertFiles() {
			document.getElementById("Button1").disabled = true;
			//启动批量生成文件,0:表示从第一个开始生成。通过递归调用ConvertFile完成批量生成文件。
			ConvertFile(ids, 0); 
		}

        function ConvertFile(idArr, index) {

            CallFileMaker({
                url: "FileMaker.jsp?id="+idArr[index], // FileMaker.jsp就是实现单个文件转换
                success: function () {
                    setProgress1(100);
					
					index++;
					setProgress2(index, idArr.length);
	
					if(index < idArr.length){
						ConvertFile(idArr, index);
					} 
                },
                progress: function (pos) {
                    setProgress1(pos);
                },
                error: function (msg) {
					document.getElementById("errorMsg").innerHTML = "发生错误: <br /> " + msg;
                    console.log("error occurred: "+msg);
                }
            });
        }
		
		function setProgress1(percent) {
			var progressBar = document.getElementById("progressBar1");
			progressBar.style.width = percent + '%';
			progressBar.innerText = percent + '%';
		}
		
		function setProgress2(index, count) {
			var progressBar = document.getElementById("progressBar2");
			progressBar.style.width = Math.round(index/count*100) + '%';
			progressBar.innerText = index + '/' + count;
		}
    </script>
	<style>
		.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;
		}
		#errorMsg{
			color: red;
		}
	</style>
</head>
<body>
    <div style="text-align: center;">
		<h3>演示:填充数据到模板中批量生成word文件</h3>
		
        <input id="Button1" type="button" value="批量生成Word文件" onclick="ConvertFiles()"/><br/>

		<div id="progressDiv">
			单文件进度:
			<div class="progressBarContainer">
			  <div id="progressBar1" class="progressBar"></div>
			</div>
			整体进度:
			<div class="progressBarContainer">
			  <div id="progressBar2" class="progressBar"></div>
			</div>
			<div id="errorMsg"> </div>
		</div>
    </div>
</body>
</html>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章