【第三方对接】使用 永中Office 实现在线 Office 整合到 Spring 项目

1、永中 Office 实现在线 Office

(1)永中 Office 介绍

永中Office官网,相比于PageOffice,个人觉得从使用方面来说,永中Office好用一点,永中Office对于开发者来说,有两个选择,一个是在线版webOffice功能较少(对于我这种需求对文档内容细节把控的来说,不考虑了),另一个是NP插件版,这个版本是和永中技术支持的小姐姐对接的,也是我推荐使用的版本

从使用层面来说,永中NP插件只需要两个东西,一个是NP插件的js文件需要引入到项目中,其次是客户端需要安装永中Office软件,因为NP插件实际上是调用本地的永中Office软件,而且永中的授权模式是客户端软件授权,也就是说,每个客户端都需要安装,并且授权才能使用,这点和PageOffice不同,PageOffice是服务端授权

永中NP插件只能使用在360浏览器,因为我的项目需要支持在Linux系统上使用

在这里插入图片描述
NP插件是在浏览器上新开一个tab,并显示内容,个人觉得最好用的方式

(2)项目需求对比

接下来继续分析项目需求,首先看这个插件能否满足,我的项目中使用的所有功能都能满足

  • 新建文件
  • 新建模板文件
  • 新建模板文件(带标签替换)
  • 编辑文件
  • 查询多个文章段落合并为一个文件(数据库多个段落存的是字符串)
  • 保存时设置其他参数值
  • 多个二进制文件合并未一个文件(多个文件合并)
  • 阅读文件(只读模式)
  • 下载文件
  • 通过代码构建整篇文章

上面的出了最后一点难度大,其他的都是常规操作,通过代码构建整篇文章意思是用代码拼接出一篇800字作文,这样好理解,包括文字段落、换行、加粗、样式、首航缩进等,一篇标准的文件,我的项目实际上是生成1:1的政府红头文件,对文字的要求更是严格

(3)基本整合过程

前面说过,NP插件只有一个js文件

在这里插入图片描述
在网页头部增加js文件就可以了

<%-- 永中office --%>
<script type="text/javascript" src="<%=path%>/static/js/yozoOffice/yozoOffice.js"></script>

(4)调用逻辑图

(5)实际使用案例

相比PageOffice,永中NP插件简洁的多,PageOffice的代码都是写在java的,永中NP的代码都是写在js中的

下面以新建一个模板文件为例,然后保存到服务器,首先前端请求后台,新建文件

前端发起请求

var param = '?title=' + encodeURI(obj.field.title)
                    + '&issueNumber=' + obj.field.issueNumber
                    + '&userIds=' + userIds.join(',')
                    + '&inviteDate=' + encodeURI(obj.field.inviteDate)
                    + '&attachment=' + encodeURI(obj.field.attachment)
                    + '&attachmentName=' + encodeURI(obj.field.attachmentName)
                    + '&delayTimeLimit=' + encodeURI(obj.field.delayTimeLimit)
                    + '&missTimeLimit=' + encodeURI(obj.field.missTimeLimit)
                    + '&orgId=${sessionScope.userInfoSession.orgId}'
                    + '&createUser=${sessionScope.userInfoSession.id}';
                window.open('<%=path%>/test/addInitStep.action' + param);

后台一样的返回一个页面

    /**
     * 添加Word页面
     *
     * @param entity
     * @param model
     * @return
     */
    @GetMapping("addInitStep")
    public String addInitStep(InvitedPaperVo entity, Model model) {

        UserInfoSession ui = (UserInfoSession) SessionUtils.getSessionAttribute(SessionConst.PC_USER_SESSION);
        UserInfoVo userInfoVo = userInfoService.getUserInfoById(ui);

        Map<String, Object> map = new HashMap<>(16);
        map.put("inviteYear", entity.getInviteDate().substring(0, 5));
        map.put("inviteDate", DateUtils.dateClearZero(entity.getInviteDate()));
        map.put("issueNumber", String.valueOf(entity.getIssueNumber()));
        map.put("content", "");
        map.put("phone", userInfoVo.getOfficeTel() != null ? userInfoVo.getOfficeTel() : "");
        map.put("createUserName", userInfoVo.getName() != null ? userInfoVo.getName() : "");
        model.addAttribute("bookmarkJson", JSON.toJSON(map));

        return "admin/invited_paper_add_office";
    }

编写返回的页面,用来承载插件显示的内容

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%String path = request.getContextPath();%>
<!DOCTYPE html>
<html>
<head>
    <title>新建模板文件</title>
    <%@ include file="./common/head.jsp" %>
</head>
<body>

<div style="width: 230px; float: left; padding: 10px;">
    <button type="button" class="layui-btn layui-btn-blue" lay-submit lay-filter="submitBtn">保存文档</button>
</div>
<div style="width: calc(100% - 250px); float: left;">
    <div id="yozo"></div>
</div>

<%@ include file="./common/js.jsp" %>
<script type="text/javascript">
    /** --------------------------------------- 初始化永中 start */
    // 初始化插件
    var Application;
    Application = init("yozo", "100%", $(window).height());
    Application.ActionEnabledWithYozoID(4, false);
    Application.openDocumentRemote(serverBaseUrl + "/office-templates/invited_paper.doc", false);
    // 处理标签替换
    var bookmarkJson = JSON.parse('${bookmarkJson}');
    var bookmarks = Application.ActiveDocument.Bookmarks;
    replaceBookmarks(bookmarkJson, bookmarks);
    /** --------------------------------------- 初始化永中 end */

    layui.config({
        base: '<%=path%>/static/layuiadmin/'
    }).extend({
        popup: 'modules/popup'
    }).use(['layer', 'form'], function () {
        var form = layui.form;

        // 提交数据
        form.on('submit(submitBtn)', function (obj) {
            layer.confirm('保存文档', {icon: 0, title: '提示'}, function () {
                var param = '?' + getParamByJson(getQueryString());
                if (Application.saveURL(serverBaseUrl + '/invitedPaper/save.action' + param)) {
                    alert('保存成功');
                    history.go(-1);
                    window.close();
                } else {
                    alert('保存失败:请检查网络连接')
                }
            });
            return false;
        });
    });
</script>
</body>
</html>

保存到服务器,这里使用了一个工具类,我是自己编写的工具类

    /**
     * 保存基本信息
     *
     * @param invitedPaperVo
     * @return
     */
    @RequestMapping("save")
    @ResponseBody
    public void save(InvitedPaperVo invitedPaperVo, HttpServletRequest request) {
        invitedPaperVo.setContent(YoZoUtils.getFileByte(request));
        invitedPaperService.saveInvitedPaper(invitedPaperVo);
    }

YoZoUtils.getFileByte(request)工具类的内容是,从当前request中读取到文件,并转为二进制,我的服务器是保存的二进制文件

import javax.servlet.http.HttpServletRequest;
import java.io.*;

/**
 * 永中插件 工具类
 *
 * @author Tellsea
 * @date 2020/09/22
 */
public class YoZoUtils {

    /**
     * 将前端请求的文件,转为byte[]类型,兼容老插件PageOffice
     *
     * @param request
     * @return
     */
    public static byte[] getFileByte(HttpServletRequest request) {
        try {
            if (request.getContentLength() > 0) {
                String localFileName = System.currentTimeMillis() + ".doc";
                String realFileName = request.getSession().getServletContext().getRealPath("/office-templates/temp/") + localFileName;
                InputStream in = request.getInputStream();
                File file = new File(realFileName);
                if (!file.getParentFile().exists()) {
                    try {
                        file.getParentFile().mkdirs();
                        file.createNewFile();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                FileOutputStream o = new FileOutputStream(file);
                byte b[] = new byte[1024];
                int n;
                while ((n = in.read(b)) != -1) {
                    o.write(b, 0, n);
                }
                o.close();
                in.close();
                byte[] bytes = fileConvertToByteArray(file);
                deleteFile(realFileName);
                return bytes;
            } else {
                System.out.println("保存的文件不能为空");
            }
        } catch (IOException e) {
            System.out.println("处理文件错误");
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 把一个文件转化为byte字节数组。
     *
     * @return
     */
    public static byte[] fileConvertToByteArray(File file) {
        byte[] data = null;
        try {
            FileInputStream fis = new FileInputStream(file);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            int len;
            byte[] buffer = new byte[1024];
            while ((len = fis.read(buffer)) != -1) {
                baos.write(buffer, 0, len);
            }
            data = baos.toByteArray();
            fis.close();
            baos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return data;
    }

    /**
     * 删除单个文件
     *
     * @param fileName 要删除的文件的文件名
     * @return 单个文件删除成功返回true,否则返回false
     */
    public static boolean deleteFile(String fileName) {
        File file = new File(fileName);
        // 如果文件路径所对应的文件存在,并且是一个文件,则直接删除
        if (file.exists() && file.isFile()) {
            if (file.delete()) {
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }


    /**
     * 强制删除
     *
     * @param fileName
     * @return
     */
    public static boolean forceDelete(String fileName) {
        File f = new File(fileName);
        boolean result = false;
        int tryCount = 0;
        while (!result && tryCount++ < 10) {
            System.gc();
            result = f.delete();
        }
        return result;
    }
}

上面是保存二进制的方法,建议保存文件到服务器,然后将访问路径保存到数据库,具体的可以和技术客服详细对接

微信公众号

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Tellsea

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

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

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

打赏作者

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

抵扣说明:

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

余额充值