pageoffice在文档在线预览,以及对word和excel的操作方面对于开发者来说确实简化了开发,使用pageoffice一年了,从刚开始接触官方文档到后来线预览的这个开发使用过程,对这个产品的使用有了一定的了解,现在来对学习和遇到的问题做个小结,我们使用的是java语言开发,买的是专业版
pageoffice文档
1 官网:http://www.zhuozhengsoft.com/
2 后端api地址:http://www.zhuozhengsoft.com/help/java3/index.html
3 前端api地址:http://www.zhuozhengsoft.com/help/js3/index.html
4 pageoffice v5 示例地址: http://localhost:8080/Samples5/index.html(自行部署)
5 技术支持文档地址:http://www.zhuozhengsoft.com/Technical/
6 PageOffice专业版 5(试用)序列号:DJMTF-HYK4-BDQ3-2MBUC
踩坑小结
自动生成表格时当表格超过20列以上时,超出了word文档边界
pageoffice自带根据窗口大小自动来调整表格列的宽度,通过WdAutoFitBehavior.wdAutoFitWindow属性来控制,但是这里面其实还是存在一些问题的,那就是它对doc格式的模板文档支持不好,(业务要求是根据上传的模板自动生成数据文件),尝试过很多种方法,发现一直都是超出边界的,后来将doc格式的模板改成docx就可以自动适配了
Table table = doc.openDataRegion("PO_table1").createTable(row, file, WdAutoFitBehavior.wdAutoFitWindow);
反复提示下载插件
2 使用5.2.0开发时在内网开发环境,安装了插件后可以正常打开,但是部署到外网环境上就一直提示需要安装插件,已经安装了还是提示要下载
官方回复:
原因:最新的谷歌和edge升级到94版本后对公网上的http请求下的非同域的http请求进行了拦截,所以就出现了目前遇到的反复提示安装pageoffice客户端的问题,暂时可以用火狐,360浏览器,搜狗等浏览器替代,或者手动对谷歌浏览器进行配置解决。从谷歌长远的目标目标来看,终极解决方案应该是所有公网上的web项目都应该使用https证书。我们针对这一问题接下来也会研究想办法,但是最好的方案是您自己将当前公网上的web项目升级为https方式的即可永久解决此问题
如果用户项目在公网上用https方案有困难,必须使用普通http和谷歌浏览器,可参考下面的解决方案
-
方案一
谷歌浏览器下手动配置解决反复提示安装PageOffice客户端问题的步骤:
步骤1:打开谷歌浏览器,在浏览器地址栏输入:
chrome://flags/#block-insecure-private-network-requests
步骤2: 找到 Block insecure private network requests. 设置为Disabled。
-
方案二(永久解决)
将pageoffice的jar包升级到5.3.0
部署到Linux上在生成数据文件时提示找不到模板
在确定文件的路径没有问题的情况找不到上传的模板文件,本地开发的时候一直都没有问题,后咨询官方得知是由于windows和Linux上的写法不一样,需要加上file:// 前缀,以下是回复
java 打开linux服务器上的文件,磁盘路径方式: 添加"file://"前缀
例如:webOpen("file://" +"/root/aaa/doc/111.doc", ...................................... );
模态窗口通过form表单隐藏input框传递参数的写法
<form id="formreport">
<input id="reportName" name="reportName" th:value="${session.value}" type="hidden" />
<input id="userName" name="userName" th:value="${session.userName}" type="hidden"/>
<div style="height:700px;" th:utext="${wordsearch}"></div>
</form>
后端获取的写法
String reportName = fs.getFormField("reportName");
String userName = fs.getFormField("userName");
模态窗口的页面展现
- pdf的展示
- word的窗口展示
生成的方法
@GetMapping("/generateWordFile")
@ApiOperation("根据模板生成word文件")
public ModelAndView wordDataTag(HttpServletRequest request, Map<String, Object> map, HttpServletResponse response) throws Exception {
response.setContentType("text/html; charset=utf-8");
PageOfficeCtrl pCtrl = new PageOfficeCtrl(request);
pCtrl.setServerPage("/poserver.zz");
pCtrl.addCustomToolButton("确认", "Save", 1);
// pCtrl.addCustomToolButton("关闭", "close()", 21);
// 隐藏标题栏
pCtrl.setTitlebar(false);
// 隐藏工具栏
pCtrl.setOfficeToolbars(false);
// 隐藏菜单栏
pCtrl.setMenubar(false);
// 禁止复制
pCtrl.setAllowCopy(false);
String missionId = request.getParameter("missionId");
String reportName = URLDecoder.decode(request.getParameter("reportName"));
String userName = URLDecoder.decode(request.getParameter("userName"));
request.getSession().setAttribute("value",reportName);
request.getSession().setAttribute("userName",userName);
String equiptype = request.getParameter("equipType");
String workId = request.getParameter("workId");
String userId =request.getParameter("userId");
// pCtrl.setCaption("word文档在线编辑11111");
// 此行必须
pCtrl.setTagId("PageOfficeCtrl1");
// 根据设备类型查找到模板,这里还需要再写一个方法
MntReportTemp reportTemp = mntReportService.findTempInfoByEquipType(equiptype);
String path = reportTemp.getFilePath() + reportTemp.getUploadTemplateName();
String tempPath = new File(path).getAbsolutePath().toString();
R r = iMntReqService.getReportData(reportName,workId);
String jsonData = ObjectMapperUtil.toJSON(r);
ReportDataDto data = ObjectMapperUtil.toObject(jsonData, ReportDataDto.class);
pCtrl.setSaveFilePage("/save?missionId="+missionId+"&&equiptype="+equiptype+"&&workId="+workId+"&&userId="+userId+"&&reportCode="+data.getReportCode());
// 定义WordDocument对象
WordDocument doc = new WordDocument();
// 设置是否禁止用户在当前Word窗口进行选取文档内容的操作
doc.setDisableWindowSelection(true);
doc.openDataTag(MntReportTagsConstants.REPORT_NAME).setValue(reportName!=null?reportName.replace("\n",""):"");
doc.openDataTag(MntReportTagsConstants.REPORT_NUMBER).setValue(data.getReportCode()!=null?data.getReportCode():"");
doc.openDataTag(MntReportTagsConstants.REQUESTER).setValue(data.getRequester() != null ? data.getRequester(): "");
doc.openDataTag(MntReportTagsConstants.TEST_LOCATION).setValue(data.getTestLocation()!=null?data.getTestLocation():"");
doc.openDataTag(MntReportTagsConstants.TEST_DATE_SHORT).setValue(data.getTestDateShort()!=null?data.getTestDateShort():"");
doc.openDataTag(MntReportTagsConstants.TEST_DATE_CHINESE).setValue(data.getTestDateChinese()!=null?data.getTestDateChinese():"");
doc.openDataTag(MntReportTagsConstants.MNT_CENTER_NAME).setValue(data.getMntCenterName()!=null?data.getMntCenterName().replace("\n",""):"");
doc.openDataTag(MntReportTagsConstants.MNT_CENTER_ADDRESS).setValue(data.getMntCenterAddress()!=null?data.getMntCenterAddress().replace("\n",""):"");
doc.openDataTag(MntReportTagsConstants.POST_CODE).setValue(data.getPostalCode()!=null?data.getPostalCode().replace("\n",""):"");
doc.openDataTag(MntReportTagsConstants.CONTACT_NO).setValue(data.getContactNo()!=null?data.getContactNo().replace("\n",""):"");
doc.openDataTag(MntReportTagsConstants.FAX).setValue(data.getFax()!=null?data.getFax().replace("\n",""):"");
doc.openDataTag(MntReportTagsConstants.MEMBERS).setValue(data.getMembers()!=null?data.getMembers():"");
doc.openDataTag(MntReportTagsConstants.WRITERNAME).setValue(data.getWriterName()!=null?data.getWriterName():"");
doc.openDataTag(MntReportTagsConstants.LEADER_NAME).setValue(data.getLeaderName()!=null?data.getLeaderName():"");
//概述
doc.openDataTag(MntReportTagsConstants.CHAPTER1).setValue(data.getChapter1()!=null?data.getChapter1():"");
//监测依据标准
doc.openDataTag(MntReportTagsConstants.TEST_STANDARD).setValue(data.getTestStandard()!=null?data.getTestStandard():"");
doc.openDataTag(MntReportTagsConstants.CHECK_STANDARD).setValue(data.getCheckStandard()!=null?data.getCheckStandard():"");
doc.openDataTag(MntReportTagsConstants.SYSNAME).setValue(data.getTestStandard()!=null?data.getTestStandard():"");
doc.openDataTag(MntReportTagsConstants.RESULTLINE).setValue(data.getResultLine()!=null?data.getResultLine():"");
doc.openDataTag(MntReportTagsConstants.CONCLUSION).setValue(data.getConclusion()!=null?data.getConclusion():"");
doc.openDataTag(MntReportTagsConstants.SYSNAME).setValue(data.getSysName()!=null?data.getSysName():"");
List<String> list = data.getMntEquipTable();
if(list!=null){
int row = list.size();
int file = list.get(0).split(",").length;
int j = 1;
// 用pageoffice模板的书签进行定位时,书签须以"PO_"开头
Table table1 = doc.openDataRegion("PO_table1").createTable(row, file, WdAutoFitBehavior.wdAutoFitWindow);
for (int i=0 ; i < row; i++) {
int h = -1;
for(int j1=0;j1<file;j1++){
h++;
table1.openCellRC(i + 1, j1+1).setValue("null".equals(list.get(i).split(",")[h])?"":list.get(i).split(",")[h]);
}
}
}
List<List<String>> li1 =data.getResultTable();
if(li1!=null){
int count = 1;
String tag = "PO_ResultTable";
for (int i = 0; i < li1.size(); i++) {
// 表示li1中只有一个list不用拼接表格
if(li1.size()==1){
//先获取内层的List
List<String> resultTable = li1.get(i);
// 行数
int row1 = resultTable.size();
int file = resultTable.get(0).split(",").length;
Table table2 = doc.openDataRegion("PO_ResultTable").createTable(row1, file, WdAutoFitBehavior.wdAutoFitWindow);
for (int i1 = 0; i1 < resultTable.size(); i1++) {
// 列数
String[] str = resultTable.get(i1).split(",");
for (int a = 0; a < str.length; a++) {
table2.openCellRC(i1 + 1, a+1).setValue("null".equals(str[a])?"":str[a]);
}
}
}else{
// 多个元素表示需要进行表格的拼接
Table table2 = null;
List<String> resultTable = li1.get(i);
int row1 = resultTable.size();
if(i<1){
int file = resultTable.get(0).split(",").length;
table2 = doc.createDataRegion("PO_ResultTable"+String.valueOf(count),DataRegionInsertType.After,"PO_ResultTable").createTable(row1, file, WdAutoFitBehavior.wdAutoFitWindow);
for(int i1 = 0; i1 < resultTable.size(); i1++){
String[] str = resultTable.get(i1).split(",");
for (int a = 0; a < str.length; a++) {
table2.openCellRC(i1 + 1, a+1).setValue("null".equals(str[a])?"":str[a]);
}
}
}else{
int file = resultTable.get(0).split(",").length;
table2 = doc.createDataRegion("PO_ResultTable"+String.valueOf(count),DataRegionInsertType.After,"PO_ResultTable"+String.valueOf(count-1)).createTable(row1, file, WdAutoFitBehavior.wdAutoFitWindow);
for(int i1 = 0; i1 < resultTable.size(); i1++){
String[] str = resultTable.get(i1).split(",");
for (int a = 0; a < str.length; a++) {
table2.openCellRC(i1 + 1, a+1).setValue("null".equals(str[a])?"":str[a]);
}
}
}
count++;
}
}
}
//设置字体,10.5f(磅)=五号字体
doc.openDataRegion("PO_ResultTable").getFont().setSize(10.5f); // 设置字体大小。以磅为单位。
doc.openDataRegion("PO_ResultTable").getFont().setName("宋体");
// doc.openDataRegion("PO_ResultTable").getFont().setBold(true);
List<List<String>> li2 = data.getAllDataTable();
int num = 1;
if(li2!=null){
String tag = "PO_allDataTable";
for (int i = 0; i < li2.size(); i++) {
// size=1表示li1中只有一个list不用拼接表格
if(li2.size()==1){
List<String> allDataTable = li2.get(i);
// 行数
int row1 = allDataTable.size();
int file = allDataTable.get(0).split(",").length;
Table table3 = doc.openDataRegion("PO_allDataTable").createTable(row1, file, WdAutoFitBehavior.wdAutoFitWindow);
for (int i1 = 0; i1 < allDataTable.size(); i1++) {
// 列数
String[] str = allDataTable.get(i1).split(",");
for (int a = 0; a < str.length; a++) {
table3.openCellRC(i1 + 1, a+1).setValue("null".equals(str[a])?"":str[a]);
}
}
}else{
Table table3 = null;
// 多个元素表示需要进行表格的拼接
List<String> allDataTable = li2.get(i);
int row1 = allDataTable.size();
if(i<1){
int file = allDataTable.get(0).split(",").length;
table3 = doc.createDataRegion("PO_allDataTable"+String.valueOf(num),DataRegionInsertType.After,"PO_allDataTable").createTable(row1, file, WdAutoFitBehavior.wdAutoFitWindow);
for (int i1 = 0; i1 < allDataTable.size(); i1++) {
String[] str = allDataTable.get(i1).split(",");
for (int a = 0; a < str.length; a++) {
table3.openCellRC(i1 + 1, a+1).setValue("null".equals(str[a])?"":str[a]);
}
}
}else{
//存放第二个之后的
int file = allDataTable.get(0).split(",").length;
table3 = doc.createDataRegion("PO_allDataTable"+String.valueOf(num),DataRegionInsertType.After,"PO_allDataTable"+String.valueOf(num-1)).createTable(row1, file, WdAutoFitBehavior.wdAutoFitWindow);
for (int i1 = 0; i1 < allDataTable.size(); i1++) {
String[] str = allDataTable.get(i1).split(",");
for (int a = 0; a < str.length; a++) {
table3.openCellRC(i1 + 1, a+1).setValue("null".equals(str[a])?"":str[a]);
}
}
}
num++;
}
}
}
// doc.openDataRegion("PO_table3").getFont().setSize(10f);
// doc.openDataRegion("PO_table3").getFont().setName("宋体");
// doc.openDataRegion("PO_table3").getFont().setBold(true);
List<List<String>> lineList = data.getResultLineList();
if(lineList!=null &&lineList.size()>0){
int count = 1;
List<String> li = null;
for(int k=0;k<lineList.size();k++){
li= lineList.get(k);
String tagName = "tag";
for(int g=0;g<li.size();g++) {
if (g == 0) {
if(k<1){
doc.createDataRegion(tagName+String.valueOf(count), DataRegionInsertType.After, "PO_resultLineList").setValue(li.get(g));
count++;
}else{
doc.createDataRegion(tagName+String.valueOf(count), DataRegionInsertType.After, tagName+String.valueOf(count-1)).setValue(li.get(g));
count++;
}
} else if (g == 1) {
doc.createDataRegion(tagName+String.valueOf(count), DataRegionInsertType.After, tagName+String.valueOf(count-1)).setValue(li.get(g));
count++;
} else if (g == 2) {
// 先保存图片再取出
String baseStr = li.get(g);
// 需要定义图片名称规则
String imageFilePath = new File(CommonConstant.IMAGE_PATH + UUID.randomUUID().toString() + "."+"jpg").getAbsolutePath().toString();;
ReportUtil.GenerateImage(baseStr,imageFilePath);
doc.createDataRegion(tagName+String.valueOf(count), DataRegionInsertType.After,tagName+String.valueOf(count-1)).setValue("[image]"+"file://"+imageFilePath+"[/image]");
count++;
} else if (g == 3) {
doc.createDataRegion(tagName+String.valueOf(count), DataRegionInsertType.After,tagName+String.valueOf(count-1)).setValue(li.get(g)+"\n");
count++;
}
}
}
}
pCtrl.setWriter(doc);
// windows上可不加"file://" 但linux上得加上
pCtrl.webOpen("file://"+tempPath, OpenModeType.docReadOnly, "无");
map.put("wordsearch", pCtrl.getHtmlCode("PageOfficeCtrl1"));
map.put("reportName", reportName);
ModelAndView mv = new ModelAndView("wordtemplate");
pCtrl.setJsFunction_BeforeDocumentClosed("BeforeDocumentClosed()");
return mv;
}
评论区