泛微ECOLOGY9知识预览文件超出大小限制的一种解决方法

问题描述如图:

在这里插入图片描述
泛微自带的文档预览由于大小限制,所以很多文档都无法打开,除非买永中或者金山付费的在线预览服务做集成。 不过现在有很多开源的在线预览软件如 onlyoffice 等,也可以实现在线预览,所以只要跟泛微OA做点集成就可以了。

实现方法:

1、泛微OA开发文档下载接口,供onlyoffice下载到本地进行转换预览。

这一步进我原来的文章:泛微ECOLOGY9实现在不登录状态根据文档ID调用文档的接口实现
https://blog.csdn.net/dycp125/article/details/130950347
不过为了满足文档多附件时的下载调用,对代码做了一点修改,调整为根据 docid和imagefileid 获取文档,或者根据 docid 获取单附件文档,或者根据 imagefileid 直接获取图片。
代码如下:

import weaver.conn.RecordSet;
import weaver.file.ImageFileManager;
import weaver.general.BaseBean;
import weaver.general.Util;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.Null;
import java.io.*;
import java.net.URLEncoder;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
/** * 下载和在线打开PDF文件 * 使用说明 http://note.youdao.com/s/77miwS0Q */
public class FileServlet extends HttpServlet {
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("application/x-zip-compressed;charset=utf-8");        // 获取http传过来的参数
        String docid = request.getParameter("docid");
        String imageid = request.getParameter("imageid");
        String method = "";
        Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");

        String sql = "";

        if(imageid !="" && imageid != null && docid !="" && docid !=null){
            try {
                if (!pattern.matcher(docid).matches()) {
                    docid = com.api.doc.detail.util.DocDownloadCheckUtil.DncodeFileid(docid);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            sql = " select docimagefile.imagefileid as imagefileid,filerealpath,imagefiletype,imagefile.imagefilename,iszip from imagefile,docimagefile "
                    + " where imagefile.imagefileid =docimagefile.imagefileid  and  docimagefile.docid='" + docid + "' and docimagefile.imagefileid='"+imageid+"'";
        }else if((imageid !="" && imageid !=null) && (docid =="" || docid == null)){
            try {
                if (!pattern.matcher(imageid).matches()) {
                    imageid = com.api.doc.detail.util.DocDownloadCheckUtil.DncodeFileid(imageid);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            sql = "select imagefileid,filerealpath,imagefiletype,imagefilename,iszip from imagefile "
                    + " where imagefileid='" + imageid + "'";
        }else if((imageid =="" || imageid ==null) && (docid !="" && docid != null)){
            try {
                if (!pattern.matcher(docid).matches()) {
                    docid = com.api.doc.detail.util.DocDownloadCheckUtil.DncodeFileid(docid);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            sql = " select docimagefile.imagefileid as imagefileid,filerealpath,imagefiletype,imagefile.imagefilename,iszip from imagefile,docimagefile "
                    + " where imagefile.imagefileid =docimagefile.imagefileid  and  docimagefile.docid='" + docid + "'";
        }
        RecordSet rs = new RecordSet();
        rs.execute(sql);
        if (rs.first()) {            // 设置http的头部,可设置下载的zip的文件名
            servletOS (response,rs.getString("imagefilename"),rs.getString("filerealpath"),rs.getString("imagefileid"), rs.getInt("iszip"));
        }
    }


    protected void servletOS (HttpServletResponse response,String imagefilename,String filerealpath, String imagefileid, Integer iszip) throws IOException {
        response.setHeader("Content-Disposition", "attachment; filename=\"" + URLEncoder.encode(imagefilename, "utf-8") + "\"");
        new BaseBean().writeLog("iszip==>" + iszip + ",filerealpath=====>" + filerealpath);
        ZipFile zf = null;
        ZipInputStream zin = null;
        ZipEntry ze = null;
        InputStream is = null;
        File file = null;
        try {
            if (1 == iszip) {
                new BaseBean().writeLog("压缩文件");
                zf = new ZipFile(filerealpath);
                zin = new ZipInputStream(new BufferedInputStream(new FileInputStream(filerealpath)));
                ze = zin.getNextEntry();
                is = zf.getInputStream(ze);
            } else {
                ImageFileManager imageFileManager = new ImageFileManager();
                imageFileManager.getImageFileInfoById(Util.getIntValue(imagefileid, 0));
                is = imageFileManager.getInputStream();
                new BaseBean().writeLog("非压缩文件");
            }
            // URLEncoder.encode(rs.getString("imagefilename"), "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        }

        byte[] buf = new byte[4096];        /* 创建输出流 */
        ServletOutputStream servletOS = response.getOutputStream();
        int readLength;
        while (((readLength = is.read(buf)) != -1)) {
            servletOS.write(buf, 0, readLength);
        }
        servletOS.flush();
        servletOS.close();
    }
}

2、泛微OA开发文档回调接口,供onlyoffice将预览的文档修改保存后或关闭时回传文档到OA。

这个接口可以跟步骤1一样,使用 servlet 的方式开发,或都使用 泛微 API接口的方式开发发布。这里使用泛微API接口方式开发发布。
** 注意接口需要放在ecology.classbean.com.api的路径下面 **

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import weaver.docs.webservices.DocAttachment;
import weaver.docs.webservices.DocInfo;
import weaver.docs.webservices.DocServiceImpl;
import weaver.hrm.User;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import java.io.*;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;


@Path("/of")
public class of {
    /**
     * 在线编辑器回调操作
     */
    private DocServiceImpl service = new DocServiceImpl();
    @POST
    @Path("/callback")
    @Produces(MediaType.TEXT_PLAIN)
    public String savedoc(@Context HttpServletRequest request, @Context HttpServletResponse response, @QueryParam("docid") int docid,@QueryParam("imagefileid") int imagefileid,@QueryParam("userid") int userid) throws Exception {

        User user=User.getUser(userid,0);
        DocInfo doc= service.getDocByUser(docid,user,"");
        DocAttachment[] das = doc.getAttachments();
        int k = 0;
        for (int i = 0; i < das.length; i++){ //多个附件时,选指定的附件
            int imageid = das[i].getImagefileid();
            if(imageid==imagefileid){
                k=i;
                break;
            }
        }
        DocAttachment da=das[k];
        //得到附件内容
        //得到附件在服务器上的绝对路径
        String filepath = da.getFilerealpath();

        Map<String, Object> res = new HashMap<>();
        Scanner scanner = new Scanner(request.getInputStream()).useDelimiter("\\A");
        String body = scanner.hasNext() ? scanner.next() : "";
        JSONObject jsonObj = JSON.parseObject(body);

        int status = (Integer) jsonObj.get("status");

        if(status == 2 || status == 3)
        {
            String downloadUri = (String) jsonObj.get("url");

            URL url = new URL(downloadUri);
            java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
            InputStream stream = connection.getInputStream();

            File savedFile = new File("d:\\WEAVER\\document\\temp\\"+da.getFilename()); //将onlyoffice回调回来的文档保存到OA服务器指定的临时目录
            try (FileOutputStream out = new FileOutputStream(savedFile)) {
                int read;
                final byte[] bytes = new byte[1024];
                while ((read = stream.read(bytes)) != -1) {
                    out.write(bytes, 0, read);
                }

                out.flush();
            }

            connection.disconnect();
            //onlyoffice 文件回调保存到临时文件夹内结束。
            // 推断文件夹或文件是否存在
            if (savedFile.exists() && savedFile.isFile()) {  // 不存在返回 false
                // 推断是否为文件
                savedFile.delete();
            }
        }
        res.put("error","0") ;
        return JSONObject.toJSONString(res);
    }
}

由于我这里只需要文档预览,不需要文档在onlyoffice中做编辑,然后上传回OA做文档更新,所以对于回调回来的文档不做更新OA操作,直接做了删除。如果有需要做更新操作的,可以在删除临时文件前增加更新上传到OA的代码。

开放白名单,使OA在不登录状态下也能访问这个接口
路径:/ecology/WEB-INF/prop/weaver_session_filter.properties,在unchecksessionurl= 尾部添加刚刚开发的接口 /api/of/callback;修改完保存,重启服务。

3、搭建onlyoffice服务

onlyoffice搭建不是本文的重点,所以就忽略了。

4、泛微OA增加onlyoffice预览页面,并在OA文档查看页面增加按钮调用预览页面。

4.1、新建预览页面

在OA ecology 下建一个onlyoffice.jsp文件。注意文件中的SQL是 MSSQL,如果使用ORACLE的数据库,则请自行修改rs2中不支持的函数,如果不修改预览页面会出错空白显示。

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@page import="weaver.conn.RecordSet"%>
<%@ page import="weaver.general.Util,weaver.conn.RecordSet" %>
<%@ page import="java.util.Map"%>
<%@ page import="java.util.HashMap"%>
<%@ page import="net.sf.json.JSONObject"%>
<%
String docid = request.getParameter("docid");
String imagefileid = request.getParameter("imagefileid");
String userid = request.getParameter("userid");
RecordSet rs = new RecordSet();
rs.executeSql("select loginid,lastname from HrmResource where id='"+userid+"'");
rs.next();
RecordSet rs1 = new RecordSet();
rs1.executeSql(" select right(imagefilename,suffixlen)as suffix,imagefilename from (select CHARINDEX('.',REVERSE(imagefile.imagefilename))-1 as suffixlen,docimagefile.docid,docimagefile.imagefileid as imagefileid,filerealpath,imagefiletype,imagefile.imagefilename,iszip from imagefile,docimagefile where imagefile.imagefileid =docimagefile.imagefileid )as PP where suffixlen>=3 and docid='"+docid+"' and imagefileid='"+imagefileid+"'");
rs1.next();
%>
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
	<head>
		<meta charset="utf-8" />
		<title>OnlyOffice转换查看</title>
		<style>
			.app {
				display: flex;
				height: calc(100vh - 10px);
				background-color: bisque;
			}

		</style>
	</head>

	<body>
		<div class="app">
			<div id="placeholder" class="placeholder">
			</div>
		</div>
		<script type="text/javascript" src="http://onlyoffice服务器地址/web-apps/apps/api/documents/api.js"></script>
		<script src="jquery.js"></script>	
		<script type="text/javascript">
			
			function handleDocType(fileType) {
				let docType = '';
				let fileTypesDoc = [
					'doc', 'docm', 'docx', 'dot', 'dotm', 'dotx', 'epub', 'fodt', 'htm', 'html', 'mht', 'odt', 'ott', 'pdf', 'rtf', 'txt', 'djvu', 'xps'
				];
				let fileTypesCsv = [
					'csv', 'fods', 'ods', 'ots', 'xls', 'xlsm', 'xlsx', 'xlt', 'xltm', 'xltx'
				];
				let fileTypesPPt = [
					'fodp', 'odp', 'otp', 'pot', 'potm', 'potx', 'pps', 'ppsm', 'ppsx', 'ppt', 'pptm', 'pptx'
				];
				if (fileTypesDoc.includes(fileType)) {
					docType = 'word';
				}
				if (fileTypesCsv.includes(fileType)) {
					docType = 'cell';
				}
				if (fileTypesPPt.includes(fileType)) {
					docType = 'slide';
				}
				return docType;
			};
			var config = {
				"height": "100%",
				"width": "100%",
				"documentType": handleDocType("<%=rs1.getString("suffix")%>"),
				"type": "desktop",
				"document": {
					"lang": "zh-CN",
					"fileType": "<%=rs1.getString("suffix")%>",
					"key": "<%=imagefileid%>", //唯一标识
					"title": "<%=rs1.getString("imagefilename")%>",
					"url": "http://OA服务器地址/file/fileservlet?docid=<%=docid%>&imageid=<%=imagefileid%>", //这里填写文档的url路径
					"permissions": {
						"comment": false, //定议是否注释文档
						"chat": true, //定义“聊天”菜单按钮是显示还是隐藏
						"copy": false,	//是否允许您将内容复制到剪贴板。默认值为true。
						"deleteCommentAuthorOnly": false,	//定义用户是否能删除他人的评论。默认值为false。
						"download": false,	//定义是否可以下载文档或仅在线查看或编辑文档。如果下载权限设置为“false”下载为菜单选项将没有。默认值为true。
						"edit": false,	//文件是否可以编辑,false时文件不可编辑
						"editCommentAuthorOnly": false,		//定义用户是否能编辑他人的评论。默认值为false。
						"fillForms": false,	//定义是否能在文档中填充表单
						"modifyContentControl": false,	//定义是否可以更改内容控件设置。仅当mode参数设置为edit时,内容控件修改才可用于文档编辑器。默认值为true。
						"modifyFilter": false,	//定义过滤器是否可以全局应用(true)影响所有其他用户,或局部应用(false),即仅适用于当前用户。如果将mode参数设置为edit,则过滤器修改仅对电子表格编辑器可用。默认值为true。
						"print": false,	//定义文档是否能打印
						"protect": false,
						"review": true,	//是否显示审阅文档菜单
						"reviewGroups": null,
						"commentGroups": {},
						"userInfoGroups": null
					}
				},
				"editorConfig": {
					"lang": "zh", //语言环境
					"mode": "view", //文档操作模式 view 视图模式不可编辑  edit 编辑模式可编辑文档
					"plugins": {
						"autostart": [
							"asc.{7470f8ef-bcb4-4f07-8887-6ebf973075cf}",
						],
						"pluginsData": []
					},
					"callbackUrl": "http://OA服务器地址/api/of/callback?docid=<%=docid%>&imagefileid=<%=imagefileid%>&userid=<%=userid%>", //保存文件时的回调地址
					"customization": {
						//匿名访问
						"anonymous": {
							"request": true,
							"label": "Guest",
						},
						//设置logo
						"logo": {
							"image": "",
							"imageEmbedded": "",
							"url": "",
						},
						"features": {
							"spellcheck": false, //定义在加载编辑器时是否自动打开或关闭拼写检查器
						},
						"about": false, //关于
						"hideRulers": true, //关闭标尺						
						"comments": false, //关闭评论
					},
					"user": {
						"group": "",
						"id": "<%=rs.getString("loginid")%>",
						"name": "<%=rs.getString("lastname")%>",
					}
				},
			}
			var docEditor = new DocsAPI.DocEditor("placeholder", config);
		</script>
	</body>
</html>

到这一步就可以测试预览服务是否正常了。
直接在浏览器输入这个预览页面的地址如:
http://OA服务器地址/onlyoffice.jsp?docid=53333&imagefileid=623445&userid=11
传入三个参数 docid 文档ID, imagefileid 文档对应的附件ID,userid 当前操作文档的用户ID
确保文档可以被正常转换加载并显示,如。
在这里插入图片描述

4.2、在OA文档查看页面增加一下第三方查看按钮

如图:
在这里插入图片描述
点击该按钮,自动跳转到4.1步骤的页面中。
具体实现如下:
在ecode中 新建文件夹,并新增一个 init.js 文件,并设置为 前置加载。
在这里插入图片描述
具体代码如下:

var k = 0;
ecodeSDK.overwritePropsFnQueueMapSet('WeaReqTop',{ //复写WeaReqTop组件
  fn:(newProps)=>{
    if (!ecodeSDK.checkLPath('/spa/document/index2file.jsp#/main/document/fileView')) return;
    var user_params = (typeof(global.localStorage.ecode_params)==='string') ? JSON.parse(global.localStorage.ecode_params) : global.localStorage.ecode_params;
    var userid = user_params._user.id; //获取当前用户ID
    function getQueryVariable(variable)
    {
        var query = window.location.href.split('?')[1];
        var vars = query.split("&");
        for (var i=0;i<vars.length;i++) {
            var pair = vars[i].split("=");
            if(pair[0] == variable){return pair[1];}
        }
        return(false);
    }
    var docid=getQueryVariable("id"); //获取URL中docid
    var imagefileid = getQueryVariable("imagefileId"); //获取URL中imagefileId
    if(k == 0 ){ //只运行一次,添加一次按钮。
        var conent = '<span style="display: inline-block; line-height: 28px; vertical-align: middle; margin-left: 10px;"><button ecid="'+docid+'"'+
    'type="button" οnclick="window.location.href=\'../../onlyoffice.jsp?docid='+docid+'&imagefileid='+imagefileid+'&userid='+userid+'\'" class="ant-btn ant-btn-primary"><span>第三方打开</span></button></span>';
    setTimeout(() => { //一开始加载时取不到元素,需要延迟一秒。
       $(".ant-btn-primary").parent().parent().eq(0).prepend(conent);
    }, 1000)
    }
    k=k+1;

  },
  order:1,
  desc:'添加第三方打开按钮'
});

总结

整体流程就是 当文档 碰到过大打不开时,点 第三方打开按钮 跳转到 onlyoffice 预览页面, 页面通过参数获取需要调用的 docid,imagefileid及userid, 然后根据参数去OA文档下载接口下载文件到onlyoffice服务器进行转换并显示出来。当浏览结束后关闭onlyoffice预览页面,5秒内触发 callback 回调接口,接文档回传到OA指定临时目录中,然后直接删除该保存下来的临时文件,结束。

  • 29
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

东枫落定

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值