【第三方對接】使用 PageOffice 實現線上 Office 整合到 Spring 專案

Tellsea 小海綿發表於2020-10-22

1、PageOffice 實現線上 Office

(1)PageOffice 介紹

PageOffice官網,在官網中可以找到各種語言的版本、案例,通過對技術客服的對接,發現PageOffice有兩個版本,一種是在瀏覽器開啟一個新的tab,然後顯示文件等(相容性差,不考慮),另一個種是開啟外掛,在桌面彈出一個視窗,相容性好一點,但是每次開啟一個文件,都會新增加一個視窗,總是需要手動關閉,每個客戶端都需要安裝PageOffice外掛

這裡有個小細節,PageOffice不支援國產化,如果專案需要支援國產化,建議使用永中Office

在這裡插入圖片描述

從上圖可以看出,PageOffice是直接獨立於瀏覽器之外的一個軟體

(2)專案需求對比

接下來繼續分析專案需求,首先看這個外掛能否滿足,我的專案中使用的所有功能都能滿足

  • 新建檔案
  • 新建模板檔案
  • 新建模板檔案(帶標籤替換)
  • 編輯檔案
  • 查詢多個文章段落合併為一個檔案(資料庫多個段落存的是字串)
  • 儲存時設定其他引數值
  • 多個二進位制檔案合併未一個檔案(多個檔案合併)
  • 閱讀檔案(只讀模式)
  • 下載檔案
  • 通過程式碼構建整篇文章

上面的出了最後一點難度大,其他的都是常規操作,通過程式碼構建整篇文章意思是用程式碼拼接出一篇800字作文,這樣好理解,包括文欄位落、換行、加粗、樣式、首航縮排等,一篇標準的檔案,我的專案實際上是生成1:1的政府紅標頭檔案,對文字的要求更是嚴格

(3)基本整合過程

這裡我就不詳細寫具體怎麼整合的了,官方都會提供案例的,我當時用的是PageOffice V4.0官網示例,然後更具下載的包,將相關jar,依賴,配置檔案新增好

  • pageoffice4.6.0.3.jar是本地jar,新增到lib下

在這裡插入圖片描述

  • 修改web.xml 配置檔案,具體的更具你自己的版本修改
    <!-- PageOffice Begin -->
    <servlet>
        <servlet-name>poserver</servlet-name>
        <servlet-class>com.zhuozhengsoft.pageoffice.poserver.Server</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>poserver</servlet-name>
        <url-pattern>/poserver.zz</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>poserver</servlet-name>
        <url-pattern>/sealsetup.exe</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>poserver</servlet-name>
        <url-pattern>/posetup.exe</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>poserver</servlet-name>
        <url-pattern>/pageoffice.js</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>poserver</servlet-name>
        <url-pattern>/jquery.min.js</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>poserver</servlet-name>
        <url-pattern>/pobstyle.css</url-pattern>
    </servlet-mapping>
    <servlet>
        <servlet-name>adminseal</servlet-name>
        <servlet-class>com.zhuozhengsoft.pageoffice.poserver.AdminSeal</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>adminseal</servlet-name>
        <url-pattern>/adminseal.zz</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>adminseal</servlet-name>
        <url-pattern>/loginseal.zz</url-pattern>
    </servlet-mapping>
    <servlet-mapping>
        <servlet-name>adminseal</servlet-name>
        <url-pattern>/sealimage.zz</url-pattern>
    </servlet-mapping>
    <mime-mapping>
        <extension>mht</extension>
        <mime-type>message/rfc822</mime-type>
    </mime-mapping>
    <context-param>
        <param-name>adminseal-password</param-name>
        <param-value>111111</param-value>
    </context-param>
    <!-- PageOffice End -->
  • 引入相應的js檔案
<%-- OfficePage --%>
<script type="text/javascript" src="<%=path%>/pageoffice.js" id="po_js_main"></script>

(4)呼叫邏輯圖

在這裡插入圖片描述

(5)實際使用案例

下面以新建一個模板檔案為例,然後儲存到伺服器

首先前端請求後臺,新建檔案

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);
POBrowser.openWindow('<%=path%>/test/addInitStep.action' + param, 'fullscreen=yes;');

編寫controller控制層,有基礎的同學應該都能讀懂

    /**
     * 新增Word頁面
     *
     * @param entity
     * @param request
     * @param model
     * @return
     */
    @GetMapping("addInitStep")
    public String addInitStep(InvitedPaperVo entity, HttpServletRequest request, Model model) throws UnsupportedEncodingException {
        PageOfficeCtrl poCtrl = new PageOfficeCtrl(request);
        poCtrl.setServerPage(request.getContextPath() + "/poserver.zz");
        poCtrl.addCustomToolButton("新建模板檔案", "Save()", 1);
        poCtrl.setCaption("標題");

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

        WordDocument doc = new WordDocument();
        doc.openDataRegion("inviteYear").setValue(entity.getInviteDate().substring(0, 5));
        doc.openDataRegion("inviteDate").setValue(DateUtils.dateClearZero(entity.getInviteDate()));
        doc.openDataRegion("issueNumber").setValue(String.valueOf(entity.getIssueNumber()));
        doc.openDataRegion("content").setValue("");
        doc.openDataRegion("phone").setValue(userInfoVo.getOfficeTel() != null ? userInfoVo.getOfficeTel() : "");
        doc.openDataRegion("createUserName").setValue(userInfoVo.getName() != null ? userInfoVo.getName() : "");

        poCtrl.setWriter(doc);
        poCtrl.webOpen(request.getContextPath() + "/office-templates/invited_paper.doc", OpenModeType.docNormalEdit, "tellsea");
        String param = "?title=" + java.net.URLEncoder.encode(entity.getTitle(), "UTF-8")
                + "&issueNumber=" + entity.getIssueNumber()
                + "&userIds=" + entity.getUserIds()
                + "&inviteDate=" + java.net.URLEncoder.encode(entity.getInviteDate(), "UTF-8")
                + "&attachment=" + java.net.URLEncoder.encode(entity.getAttachment(), "UTF-8")
                + "&attachmentName=" + java.net.URLEncoder.encode(entity.getAttachmentName(), "UTF-8")
                + "&delayTimeLimit=" + java.net.URLEncoder.encode(entity.getDelayTimeLimit(), "UTF-8")
                + "&missTimeLimit=" + java.net.URLEncoder.encode(entity.getMissTimeLimit(), "UTF-8");
        poCtrl.setSaveFilePage(request.getContextPath() + "/invitedPaper/save.action" + param);
        model.addAttribute("poCtrl", poCtrl);
        return "admin/invited_paper_add_office";
    }

controller返回的是一個頁面,提供給PageOffice顯示,編寫頁面

<%@ 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>
<%@ include file="./common/js.jsp" %>
<div style="margin:auto; width: 100%; height: calc(100vh - 25px);">
    ${poCtrl.getHtmlCode("PageOfficeCtrl1")}
</div>

<script type="text/javascript">
    function Save() {
        document.getElementById("PageOfficeCtrl1").WebSave();
        if (document.getElementById("PageOfficeCtrl1").CustomSaveResult == "ok") {
            // document.getElementById("PageOfficeCtrl1").Alert('儲存成功!');
            if (confirm('儲存成功,關閉當前視窗?')) {
                window.external.close();
            }
        }
    }
</script>
</body>
</html>

然後編寫儲存請求,從controller中的poCtrl.setSaveFilePage可以得到儲存路徑

    /**
     * 儲存基本資訊
     *
     * @param invitedPaperVo
     * @return
     */
    @PostMapping("save")
    @ResponseBody
    public void save(InvitedPaperVo invitedPaperVo) {
        FileSaver fs = new FileSaver(SessionUtils.getRequest(), SessionUtils.getResponse());
        invitedPaperVo.setContent(fs.getFileBytes());
        invitedPaperService.saveInvitedPaper(invitedPaperVo);
        fs.setCustomSaveResult("ok");
        fs.close();
    }

上面是儲存二進位制的方法,建議儲存檔案到伺服器,然後將訪問路徑儲存到資料庫,具體的可以看官方給的示例

相關文章