**本文地址:**https://zechariahzheng.github.io/posts/vue2.x%E9%80%82%E9%85%8Dwps%E5%8A%A0%E8%BD%BD%E9%A1%B9/

wps加载项概述

​ WPS 加载项是一套基于 Web 技术用来扩展 WPS 应用程序的解决方案。每个 WPS 加载项都对应打开了一个网页,并通过调用网页中 JavaScript 方法来完成其功能逻辑。 WPS 加载项打开的网页可以直接与 WPS 应用程序进行交互,同时一个 WPS 加载项中的多个网页形成了一个整体, 相互之间可以进行数据共享。 开发者不必关注浏览器兼容的问题,因为 WPS 加载项的底层是以 Chromium 开源浏览器项目为基础进行的优化扩展。 WPS 加载项具备快速开发、轻量化、跨平台的特性,目前已针对Windows/Linux操作系统进行适配。

​ 简而言之:wps加载项不需要关注浏览器兼容的问题,之前的wps内嵌模式只适用于支持NPAPI的浏览器。

1. wps加载项准备工作

1.1 http上传下载服务

wps加载项需要wps程序先从远程拉取wps加载项的内容至本地,故需要一个http上传下载服务为wps程序提供加载项。wps官方程序提供的是nodejs的http上传下载服务,我这里提供的是一个简单的基于java的http上传下载服务。这里提供一个webservlet服务,代码如下:

package com.zzs.demo;

/**
 * @Author ZechariahZheng
 * @Date 2021-4-20 16:32
 * @Version 1.0
 * @description
 */
import java.io.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.net.URLEncoder;
import java.util.regex.Matcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.springframework.beans.factory.annotation.Value;

@WebServlet({ "/WpsServlet/*" })
@Slf4j
public class HelloServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    private static final boolean isWin = System.getProperty("os.name").toLowerCase().contains("win");

    @Value("${wps.oa.downloadfile}")
    String downloadPath;

    @Value("${wps.oa.uploadfile}")
    String uploadPath;

    /**
     * 下载文件
     *
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String uri = request.getRequestURI();
        String filename = uri.substring(uri.lastIndexOf("/")+1);
        String path = uri.substring(uri.indexOf("/", 1), uri.lastIndexOf("/"));
        log.info("----path is:"+path);
        log.info("----filename is:"+filename);
        if (filename == null || filename.isEmpty()) {
            log.info("please set file name ");
        } else {
            // 假设文件都在服务的根目录下
            //String realFileName = request.getServletContext().getRealPath("/") + filename;
            //如果是windows机器,替换路径
            path = path.replaceAll("/", Matcher.quoteReplacement(File.separator))+'\\';
            String realFileName = downloadPath + path + filename;
            log.info("------"+realFileName);
            // 实例化一个向客户端输出文件流
            OutputStream outputStream = response.getOutputStream();
            // 输出文件用的字节数组,每次向输出流发送600个字节
            byte b[] = new byte[600];
            // 要向客户端输出的文件
            File fileload = new File(realFileName);
            log.info(filename);
            String utf8filename = URLEncoder.encode(filename, "UTF-8");
            log.info(utf8filename);
            response.setHeader("Content-disposition", "attachment; filename=" + utf8filename);
            // 通知客户端:文件的MIME类型
            response.setContentType("application/msword");
            // 通知客户端:文件的长度
            long fileLength = fileload.length();
            String length = String.valueOf(fileLength);
            response.setHeader("Content-length", length);
            // 读取文件,并发送给客户端下载
            FileInputStream inputStream = new FileInputStream(fileload);
            int n = 0;
            while ((n = inputStream.read(b)) != -1) {
                outputStream.write(b, 0, n);
            }
            inputStream.close();
            outputStream.close();
        }
    }

    /**
     * 上传文件
     *
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");
        log.info("添加任务");
        HttpSession session = request.getSession();
        Cookie[] cookies = request.getCookies();
        String value = "";

        try {
            DiskFileItemFactory factory = new DiskFileItemFactory();
            ServletFileUpload upload = new ServletFileUpload((FileItemFactory) factory);
            upload.setHeaderEncoding("UTF-8");

            List items = upload.parseRequest(request);
            boolean isOk = false;
            Map<Object, Object> param = new HashMap<>();
            for (Object object : items) {
                FileItem fileItem = (FileItem) object;
                if (fileItem.isFormField()) {
                    log.info(fileItem.getFieldName() + ":" + fileItem.getString("utf-8") + ", size:"
                            + fileItem.getSize());
                    param.put(fileItem.getFieldName(), fileItem.getString("utf-8"));
                    continue;
                }
                String fieldName = fileItem.getFieldName();
                // 必须要有文件名,需要客户端传参时注意
                String fileName = fileItem.getName();
                if (fileName.equals("blob"))
                    if (param.containsKey("filename")) {
                        fileName = param.get("filename").toString();
                    } else if (param.containsKey("fileName")) {
                        fileName = param.get("fileName").toString();
                    }
                //String filePath = request.getSession().getServletContext().getRealPath("/") + fileName;
                String filePath = uploadPath + fileName;
                log.info(fieldName + ":" + filePath);

                FileOutputStream fileOut = new FileOutputStream(filePath);
                InputStream in = fileItem.getInputStream();
                byte[] buffer = new byte[1024];
                int len = 0;
                while ((len = in.read(buffer)) > 0) {
                    fileOut.write(buffer, 0, len);
                }
                in.close();
                fileOut.close();
                response.setHeader("Content-disposition", "attachment; filename*=UTF-8''" + fileName);
                response.getWriter().write(fileName.concat("上传成功"));

                return;
            }
        } catch (FileUploadException e) {

            e.printStackTrace();
        }

        response.sendError(404, "no ssison");
    }
}

1.2 下载文件

​ 将wps加载项文件jsplugins.xml存放在某个目录中,该目录在application.properties文件夹进行配置如图所示:(我配置在E:/file)

image-20210625221300717

jsplugins.xml文件配置如下:

<!-- WPS加载项配置信息,在线和离线只有一个生效,不可同时存在 -->
<!-- WPS加载项:在线模式配置	Start -->

<!-- https://kdocs.cn/l/cBk8tsBIf [金山文档] jsplugins.xml配置文档.docx -->
<!--<jsplugins> -->
<!--<jspluginonline name="EtOAAssist" type="et" url="http://127.0.0.1:3888/plugin/et"/> -->
<!--<jspluginonline name="WpsOAAssist" type="wps" url="http://127.0.0.1:8080/WpsServlet/WpsOAAssist"/> -->
<!--<jspluginonline name="WppOAAssist" type="wpp" url="http://127.0.0.1:3888/plugin/wpp"/> -->
<!--<</jsplugins>-->
<!-- WPS加载项:在线模式配置	End -->

<!-- WPS加载项:离线模式配置	Start -->
<jsplugins>
<!--<jsplugin name="EtOAAssist" type="et" url="http://127.0.0.1:3888/plugins/v0.1/EtOAAssist.7z" version="0.1" /> -->
	<jsplugin name="WpsOAAssist" type="wps" url="http://127.0.0.1:8080/WpsServlet/WpsOAAssist.7z" version="0.1" />
<!--<jsplugin name="WppOAAssist" type="wpp" url="http://127.0.0.1:3888/plugins/v0.1/WppOAAssist.7z" version="0.1" /> -->
</jsplugins>
<!-- WPS加载项:离线模式配置	End -->

这里采用wps加载项离线模式,在file文件夹中保存jsplugins.xml文件和WpsOAAssist.7z加载项文件。

1.3 wps配置设置

​ 设置wps的配置文件,进行wps安装目录的如:D:\Kingsoft\WPS Office\11.8.2.8875\office6\cfgs,修改oem.ini文件。将JSPluginsServer配置为刚刚设置的下载路径,如下:

[Support]
Support2016SN=true
JsApiPlugin=true
JsApiShowWebDebugger=true

[setup]
OfdDefaultServiceProvider=0
LANG_ID=2052
BUILD_VERSION=11.8.2.8875
Industry=
SourceDir=oeminfo

[Server]
JSPluginsServer=http://127.0.0.1:8080/WpsServlet/jsplugins.xml
FinishActionFile=oeminfo\oem.exe
FinishActionParameter="/copydir=OemFile\\office6 /ShellVarContext=all /RelativeDir=INSTDIR /todir='office6'"
FinishActionWait=1
PlacedDir2=
FinishActionFile2=oeminfo\oem.exe
FinishActionParameter2="/leveladmin=1 /regdllfile='office6\\wpsdocframe.dll' /ShellVarContext=all /RelativeDir=INSTDIR"
FinishActionWait2=1
UninstActionFile=office6\cfgs\oeminfo\oem.exe
UninstActionParameter="/leveladmin=1 /unregdllfile='office6\\wpsdocframe.dll' /ShellVarContext=all /RelativeDir=INSTDIR"
UninstActionWait=1
UninstActionFile2=office6\cfgs\oeminfo\oem.exe
UninstActionParameter2="/ShellVarContext=all /RelativeDir=INSTDIR /rmdir='office6'"
UninstActionWait2=1
InstExeCount=2
UninstExeCount=2

[feature]
xn3QfP-XIpyKSU9I2xbCubad10=gn3QfP-XIpy4U3A385v-NVGs10

2. vue适配wps

​ wps提供官方的文件wpsjsrpcsdk.js,我对其做了重新封装wpsInvoke.js,如下:


export function _WpsInvoke(funcs, front, jsPluginsXml) {
    var bUseHttps = false;
    var info = {};
    info.funcs = funcs;    
    var func = bUseHttps ? WpsInvoke.InvokeAsHttps : WpsInvoke.InvokeAsHttp;
    func(WpsInvoke.ClientType.wps, // 组件类型
        "WpsOAAssist", // 插件名,与wps客户端加载的加载的插件名对应
        "dispatcher", // 插件方法入口,与wps客户端加载的加载的插件代码对应,详细见插件代码
        info, // 传递给插件的数据        
        function (result) { // 调用回调,status为0为成功,其他是错误
            if (result.status) {
                if (bUseHttps && result.status == 100) {
                    WpsInvoke.AuthHttpesCert('请在稍后打开的网页中,点击"高级" => "继续前往",完成授权。')
                    return;
                }
                alert(result.message)

            } else {
                console.log(result.response)
                showresult(result.response)
            }
        },
        front,
        jsPluginsXml)
}

vue初始化wps的时候,先导入两个js文件,然后初始化。如下:

import {wps_sdk} from '../api/wpsjsrpcsdk.js'
import {_WpsInvoke} from '../api/wpsInvoke.js'

createDocument() {    //初始化插件
            var uploadPath = prompt("请输入文档上传路径:", "http://127.0.0.1:8000/WpsServlet/")
            var uploadFieldName = prompt("请输入文档上传到业务系统时自定义字段:", ".doc")
            _WpsInvoke([{
                "NewDoc": {
                    "uploadPath": uploadPath, // 保存文档上传路径
                    "uploadFieldName": uploadFieldName,
                }
            }],
            true,
            "http://127.0.0.1:8080/WpsServlet/jsplugins.xml") //后端提供的下载路径
        },

以上所有代码下载链接:

https://download.csdn.net/download/zishengzheng/19840189

wps加载项官方代码:

https://code.aliyun.com/zouyingfeng/wps/tree/master/oaassist

Logo

前往低代码交流专区

更多推荐