OnlyOffice 集成

ONLYOFFICE 是一个开源办公套件,包括文本文档、电子表格、演示文稿和可填写表单的编辑器

在线编辑文档过程

界面效果

通过附件组件上传文档

1756689523491

点击“在线编辑”按钮,打开文档编辑器页面

1756689637991

1756689654687

编辑后关闭文档编辑器页面

1756691493497

代码逻辑

1756948202933

动作 后端处理 前端处理 OnlyOffice处理
打开文档编辑器页面 1 在获取配置信息服务中:
根据 storeFileName 生成文档 url
根据 storeFileName 和业务主键生成 key
根据 OnlyOffice 要求生成 token
2 在回调服务中:
返回{"error":0}
1 调用后端服务:
传入业务主键、附件 storeFileName
获取配置信息
2 使用配置信息,显示编辑器
1 使用配置中的 url 打开文档
2 调用回调服务
* 传入 status=1,表示打开编辑器
关闭文档编辑器页面 在回调服务中:
使用传入的 url 下载文档
重新生成 storeFileName
上传文档至minIO
从 key 中获取业务主键,修改附件列
在回调服务完成后,刷新业务数据,
获取最新的 storeFileName,
以便再次编辑文档
1 保存文档
2 调用回调服务:
传入 status=2,表示已保存
传入修改后文档的 url

由于 OnlyOffice 需要打开文档和调用回调服务,因此以下两个 API 需要设置匿名用户访问权限

  • 附件的获取文件 url
  • 回调服务

1756692640483

安装 OnlyOffice

在 k8s newdao-common 名空间中安装

平台测试过的 onlyoffice 有两个,7.3.3, 9.0.4;如果要使用9.0.4,需要先使用7.3.3启动起来(数据库等都初始化完成),然后再切换成9.0.4;直接使用9.0.4有数据库初始化问题。

onlyoffice 的安装包是后面加入的,如果 onlyoffice 的安装包已经包含在平台的安装包中,直接执行第2步就可以了;否则执行第1步,否则会安装失败。

安装步骤如下:

用 ssh 进入到平台的 master 机器

第1步 进入 /usr/local/newdao/applications/common/common-onlyoffice/templates/onlyoffice 目录中

用 vim 编辑 pv-pvc.yaml

  • 把 {{ .Values.nfs.host }},{{ .Values.nfs.volume }} 替换成平台时实际的值
  • 删除 mountOptions: 部分

用 vim 编辑 onlyoffice.yaml

  • 把 {{ .Values.domains.localRegistry }} 替换成平台时实际的值

第2步 进入 /usr/local/newdao/install 目录中

执行下面的命令

source init.conf
source helm-utils.sh
install_chart $NAMESPACE_PREFIX$COMMON_NAMESPACE $NAMESPACE_PREFIX$COMMON_NAMESPACE'-onlyoffice' ../applications/common/common-onlyoffice

安装后提供

修改 savetimeoutdelay 参数

关闭 OnlyOffice 文档编辑器,默认5秒后触发回调,可通过修改 savetimeoutdelay 参数调整延迟时间,如调整为 1000 毫秒(或更低)。调整步骤如下:

  • 进入k8s-newdao common-onlyoffice 终端
  • 进入 /var/www/onlyoffice/documentserver/npm 目录
  • 修改 local.json /var/www/onlyoffice/documentserver/npm# ./json -q -f /etc/onlyoffice/documentserver/local.json -I -e "this.services.CoAuthoring.server = {}" /var/www/onlyoffice/documentserver/npm# ./json -q -f /etc/onlyoffice/documentserver/local.json -I -e "this.services.CoAuthoring.server.savetimeoutdelay = 1000"
  • 查看修改结果 /var/www/onlyoffice/documentserver/npm# cat /etc/onlyoffice/documentserver/local.json
  • 重启服务 /var/www/onlyoffice/documentserver/npm# supervisorctl status /var/www/onlyoffice/documentserver/npm# supervisorctl restart ds:docservice

后端服务

使用 OnlyOffice 需要定义两个后端服务

  • 回调服务:提供给 OnlyOffice 调用
  • 获取配置信息:初始化文档编辑器时调用

回调服务

OnlyOffice 在打开文档编辑器、关闭文档编辑器时,会发送一个 POST 请求,并要求返回 JSON 字符串 {"error":0}

在服务中,添加“文档编辑回调”服务,请求方法设置为 POST,添加一个请求体参数,如下图所示

1756463206582

打开文档编辑器时,传入参数如下

{
  "actions": [{"type": 1,
      "userid": "78e1e841"}
  ],
  "key": "Khirz6zTPdfd7",
  "status": 1,
  "users": ["6d5a81d0", "78e1e841"]
}

关闭文档编辑器时,传入参数如下

{
  "actions": [{
      "type": 0,
      "userid": "78e1e841" 
  }],
  "changesurl": "https://documentserver/url-to-changes.zip",
  "history": {
    "changes": changes,
    "serverVersion": serverVersion
  },
  "filetype": "docx",
  "key": "Khirz6zTPdfd7",
  "status": 2,
  "url": "https://documentserver/url-to-edited-document.docx",
  "users": ["6d5a81d0"]
}

从参数中获取 status 、url 和 key

  • 当 status 等于2时,表示文档已更改
  • 使用 url 下载文档,再上传到 minIO
  • 从 key 中获取业务数据主键,将新文档(修改后的文档)的信息写入业务数据表

文档编辑回调服务的示例代码如下

public String editCallback(String info) throws Exception {
    //获取传入的参数
    JSONObject fileInfo = JSON.parseObject(info);

    //获取状态
    Integer status = fileInfo.getInteger("status");
    if(status == 2){
        try{
            //获取业务数据
            String id = fileInfo.getString("key");
            id = id.substring(0,32);
            Product product = productMapper.findByPrimaryKey(id);

            String files = product.getFiles();
            JSONArray fileArr = JSONArray.parseArray(files);
            if(fileArr.size() > 0){
                //获取文件名
                String realFileName = fileArr.getJSONObject(0).getString("realFileName");
                //生成新的文件存储名,因为minIO对storeFileName有缓存,所以每次都需要生成新的storeFileName
                String uuid = UUID.randomUUID().toString().replace("-", "");
                String storeFileName = org.apache.http.client.utils.DateUtils.formatDate(new Date(), "/yyyy/M/d")
                        + "/anoy_" + uuid + realFileName;

                //上传文件
                uploadFiled(fileInfo.getString("url"),storeFileName);

                //写入新上传文件的信息
                JSONArray newFileArr = new JSONArray();
                JSONObject newFileJson = new JSONObject();
                newFileJson.put("storeFileName", storeFileName);
                newFileJson.put("realFileName", realFileName);
                newFileArr.add(newFileJson);
                product.setFiles(newFileArr.toJSONString());
                productMapper.updateByPrimaryKey(product);
            }
        }catch (Exception e) {
            e.printStackTrace();
            return "{\"error\":1}";
        }
    }
    return "{\"error\":0}";
}

private void uploadFiled(String fileUrl,String storeFileName) throws Exception {
    //将外网地址改为内网地址
    String downloadUri = fileUrl.replace("https://","");
    downloadUri = downloadUri.substring(downloadUri.indexOf("/"));
    downloadUri = "http://onlyoffice-svc.newdao-common" + downloadUri;

    //下载文件到本地
    URL url = new URL(downloadUri);
    String filePath = ContextUtil.getEnv("JUSTEP_HOME") + "/model-user/temp.docx";
    Path outputPath = Paths.get(filePath);
    Files.copy(url.openStream(), outputPath, StandardCopyOption.REPLACE_EXISTING);
    //上传文件到minIO
    File file = new File(filePath);
    StorageApi storageApi = StorageClient.getInstance();
    storageApi.postObject(file, storeFileName, 0);
}

代码说明

  • key:文档唯一标识。在“获取配置信息”服务中设置,使用业务数据主键 + storeFileName 的一部分拼接而成
  • storeFileName:minIO 中的文件标识。由于 minIO 缓存 storeFileName,所以每次上传文件都需要生成新的 storeFileName
  • storeFileName 的格式为:/年/月/日/anoy_ + 32位UUID + 文件名
  • downloadUrl:下载文件地址,从 OnlyOffice 传入的 url 的域名是 OnlyOffice 的外部访问地址,在服务中访问需要替换为内部访问地址。如果使用本地 IDE 调试,不要直接使用 OnlyOffice 传入的 url,因为在本地 IDE 中既不能访问 OnlyOffice 的外部访问地址,也不能访问 OnlyOffice 的内部访问地址,可以暂时使用附件的访问地址替代,切换到云 IDE 后,再使用 OnlyOffice 传入的 url
  • 存储临时文件:临时文件可以存储到 JUSTEP_HOME/model-user 目录下,使用 ContextUtil.getEnv("JUSTEP_HOME") 获取环境变量的值

获取配置信息

OnlyOffice 的文档编辑器初始化时,需要传入 config 参数,格式如下

config: {
    document: {
        fileType: "文件类型",//本例使用docx
        key: "文档key",//本例使用业务数据主键+文件的storeFileName
        title: "文档标题.docx",//本例使用文档的realFileName
        url: "文档访问路径"//本例使用/storage/getObject?storeFileName=
    },
    documentType: "word",
    editorConfig: {
        callbackUrl: "回调服务地址"//本例使用文档编辑回调服务/main/onlyoffice/editcallback
    },
    token: "token"//通过createToken方法生成
}

其中

  • key 是文档唯一标识,只能包括字母、数字、-_=字符,最大长度128位。必须和文档版本相匹配。
    • OnlyOffice 会缓存 key,如果文档已经修改,使用之前打开文档时用过的 key,会提示文档版本发生变化,并以只读方式显示文档。因此文档修改后,务必使用新的 key 打开文档
    • 在本例中,key 由业务主键和 storeFileName 组成,文档修改后,会在服务端生成新的 storeFileName,并更新数据表。在前端关闭文档编辑器后,必须刷新业务数据,以获取最新的 storeFileName,保证再次编辑文档时的 key 是没有使用过的
  • url 是文件访问地址,用于在 OnlyOffice 中打开文档。使用附件组件上传的文件,文件访问地址为:/storage/getObject?storeFileName=
  • callbackUrl 是回调服务地址,用于在 OnlyOffice 中调用回调服务,使用上一节中添加的回调服务的地址
  • token 是令牌,使用安装时设置的 token secret 生成

在服务中,添加“获取 config”服务,请求方法设置为 GET,添加三个请求参数,如下图所示

1756463160449

public String getConfig(String storeFileName,String title,String dataId) throws Exception {
    JSONObject document = new JSONObject();
    document.put("fileType", "docx");
    document.put("title", title);
    //从storeFileName中获取uuid,作为dataId合成为key
    int pos = storeFileName.indexOf("anoy_");
    document.put("key", dataId + storeFileName.substring(pos, pos + 37));

    HttpServletRequest request  = SpringWebUtil.getRequest();
    String url = RequestUtil.buildRequestUrl(request,ContextUtil.getServiceName(),"/storage/getObject?storeFileName=" + URLEncoder.encode(storeFileName, "UTF-8"));
    document.put("url", url);

    JSONObject editorConfig = new JSONObject();
    String callbackUrl = RequestUtil.buildRequestUrl(request,ContextUtil.getServiceName(),"/main/onlyoffice/editcallback");
    editorConfig.put("callbackUrl",  callbackUrl);

    JSONObject config = new JSONObject();
    config.put("document", document);
    config.put("documentType", "word");
    config.put("editorConfig", editorConfig);

    return createToken(config.toJSONString());
}

private String createToken(String config) throws Exception {
    JSONObject jsonObject = JSON.parseObject(config);
    String tokenSecret = ONLYOFFICE_TOKEN_SECRET;
    Map<String, Object> payloadClaims = BeanUtil.beanToMap(jsonObject);
    String token = "";
    try {
        Signer signer = HMACSigner.newSHA256Signer(tokenSecret);
        JWT jwt = new JWT();
        for (String key : payloadClaims.keySet()) {
            jwt.addClaim(key, payloadClaims.get(key));
        }
        token = JWT.getEncoder().encode(jwt, signer);
    } catch (Exception e) {
        token = "";
    }
    jsonObject.put("token", token);
    return jsonObject.toJSONString();
}

权限设置

由于 OnlyOffice 需要打开文档和调用回调服务,因此以下两个 API 需要设置匿名用户访问权限

  • 附件的获取文件 url
  • 回调服务

匿名用户访问权限在设计时和运行时皆可配置

  • 在设计时配置,发布后会带入运行时,运行时无需配置。但是由于调试运行时的匿名用户权限会被正式运行时的匿名用户权限覆盖,因此在设计时配置后,需要发布一次,使得调试运行时可以使用配置的匿名用户权限
  • 在运行时配置,匿名用户权限没有跟随应用资源,在其他租户中添加该应用时,需要手动配置

下面介绍设计时配置的步骤

进入角色权限设置

切换到“页面”设计区,点击右上角齿轮按钮,在弹出的菜单中,选择“角色权限设置”,打开角色权限设置对话框

1756695617352

添加 API 权限

进入权限管理

点“权限管理”按钮,打开“服务权限配置”对话框

1756695595898

添加 API 权限

点击“API权限”页签,点击“添加接口”按钮,在标签中输入获取文档、在路径中输入storage/getObject,在标识中输入storage/getObject:GET,如下图所示,点击确定按钮关闭对话框

1756695578349

添加匿名用户角色

在“角色权限设置”对话框中,点击添加按钮,打开“服务角色权限设置”对话框,在角色标识中输入 anonymous,在角色名称中输入匿名用户,如下图所示

1756695660039

分配匿名权限

在上图中,点击“API 权限”页签,勾选“文档编辑回调”和“获取文档”两个 API,如下图所示,点击保存按钮关闭对话框

1756695679116

保存配置

最后点击“保存配置文件”按钮,存储配置信息。

1756696885901

发布应用

由于设计时的匿名用户权限会被运行时的覆盖,因此在设计时配置匿名用户权限后,需要发布一次。点击右上角的发布按钮,发布类型选择应用,点击“立即发布”按钮发布应用。发布完成后,OnlyOffice 可以直接访问文档和回调服务。

1756697032377

前端页面

OnlyOffice 提供三种方法显示文档编辑器

  • 使用 vue 组件
  • 使用 react 组件
  • 使用加载动态 JS

使用 vue 组件

安装 npm 包

安装 npm 包 @onlyoffice/document-editor-vue,将生成的 @onlyoffice 目录复制到 IDE 中的 model/UI2/pcx/node_modules 目录下,如下图所示。引入 npm 包参考《引入第三方 npm 包

1756461189124

添加页面

添加一个空白页面,作为文档编辑器的页面。添加三个页面参数,如下图所示

1756461537862

添加“获取 config”服务组件,添加页面的数据初始化事件

1756705480616

在数据初始化事件中,调用“获取 config”服务,传入三个参数,返回值写入 state

let onPageInitState = async (event) => {
    //获取config
    let { data } = await $page.comp("getConfigRequest").send({ 
        dataId: $page.params.dataId,
        title: $page.params.doctitle,
        storeFileName: $page.params.storeFileName
    });
    state.config = data;
}

引用 OnlyOffice 的 vue 组件,初始化 state

import { DocumentEditor } from "@onlyoffice/document-editor-vue";
let state = reactive({ config: {} });

定义渲染文档编辑器的方法

let documentServerUrl = "https://onlyoffice" + window.location.host.substr(window.location.host.indexOf(".")) + "/";

let renderEditor = () => {
    if (state.config && state.config != {}) {
        return (
            <DocumentEditor id="docxEditor" documentServerUrl={documentServerUrl} config={state.config} />
        )
    }
}

在 w 源码中调用渲染方法

{renderEditor()}

1756461388147

打开页面

打开页面系统提供三种方式:打开门户页、打开对话框、打开抽屉。本文介绍前两种

打开门户页运行效果,如下图所示

1756706178724

打开对话框的运行效果,如下图所示

1756706210155

门户页

使用页面组件的 navigateTo 方法打开门户页,示例代码如下

let mainData = useData("mainData");

let onEditOnlineBtnClick = ({row}) => async (event) => {
    //保存数据,文档编辑回调服务中会修改本行数据
    await mainData.saveData();
    //获取附件列的 JSON 对象
    let json = JSON.parse(row.files || "[]");
    if (json.length > 0) {
        let storeFileName = json[0].storeFileName;
        let realFileName = json[0].realFileName;
        //打开在线编辑页面
        $page.navigateTo({
            url: $page.getUIUrl("$UI/pcx/onlyoffice/editPage.w?title=在线编辑文档&storeFileName="
                + storeFileName + "&doctitle=" + realFileName + ".docx&dataId=" + row.fid)
        });
    }
}
对话框

在页面上添加对话框组件,页面文件属性选择文档编辑器页面,开启组件引用,如下图所示

1756706681166

在弹出层配置中,设置标题和宽度,如下图所示

1756706557099

在按钮的点击事件中,调用对话框组件的 open 方法打开对话框,示例代码如下

let onEditDialogBtnClick = ({row}) => async (event) => {
    //保存数据,文档编辑回调服务中会修改本行数据
    await mainData.saveData();
    //获取附件列的 JSON 对象
    let json = JSON.parse(row.files || "[]");
    if (json.length > 0) {
        let storeFileName = json[0].storeFileName;
        let realFileName = json[0].realFileName;
        //打开在线编辑页面
        $page.comp("editDialog").open({
            params: {
                storeFileName: storeFileName,
                doctitle: realFileName,
                dataId: row.fid
            }
        });
    }
}

关闭页面

关闭页面时,触发页面组件的卸载事件,如下图所示

1756706730160

在卸载事件中,给父页面发送消息,以便父页面接收到消息后刷新业务数据

let onPageUnload = (event) => {
    //关闭页面给父页面发送消息
    $page.getOpener().postMessage({data:"onlyoffice-close"});
}

父页面收到消息后,触发页面组件的接收消息事件,如下图所示

1756706798915

在接收消息事件中,首先显示遮罩,2秒后刷新业务数据,刷新后关闭遮罩,示例代码如下

//在线编辑页面关闭后触发
let onPageMessage = async (event) => {
    if (event.data == "onlyoffice-close") {
        //等2秒,刷新数据
        $page.setState({ loading: { fullscreen: true } });
        window.setTimeout(async () => {
            await mainData.refreshData();
            $page.setState({ loading: false });
        }, 2000);
    }
}

特别说明

  • 上面代码中的2秒是怎么来的?
    • 关闭 OnlyOffice 的文档编辑器5秒后,OnlyOffice 调用回调服务,在回调服务中,实现文档的下载、上传至 minIO、以及更新业务数据
    • 5秒是默认值,可调整,本例调整为1秒。即关闭文档编辑器1秒后,执行回调服务修改业务数据,2秒后前端刷新业务数据
    • 2秒是一个估算值,需要根据最终运行环境进行适当调整
  • 如果要实现在后端回调服务处理完成后,前端页面刷新业务数据,使用事件中心的消息推送实现,参考《前端消息通讯 centrifugoService

使用 react 组件

安装 npm 包

安装 npm 包 @onlyoffice/document-editor-react,将生成的 @onlyoffice 目录复制到 IDE 中的 model/UI2/pcx/node_modules 目录下,如下图所示。引入 npm 包参考《引入第三方 npm 包

1756707708297

添加页面

添加一个空白页面,作为文档编辑器的页面。添加三个页面参数,如下图所示

1756461537862

添加“获取 config”服务组件,添加页面的数据初始化事件

1756707913313

在数据初始化事件中,调用“获取 config”服务,传入三个参数,返回值写入 state

    onPageInitState = async (event) => {
        //获取config
        let { data } = await this.comp("getConfigRequest").send({
            dataId: this.params.dataId,
            title: this.params.doctitle,
            storeFileName: this.params.storeFileName
        });
        this.setState({ "config": data });
    }

引用 OnlyOffice 的 react 组件,初始化 state

import { DocumentEditor } from "@onlyoffice/document-editor-react"

    constructor(props, context) {
        super(props, context);
        this.setState({ "config": {} });
    }

定义渲染文档编辑器的方法

    renderEditor = () => {
        if (this.state.config && this.state.config != {}) {
            let documentServerUrl = "https://onlyoffice" + window.location.host.substr(window.location.host.indexOf(".")) + "/";
            return (
                <DocumentEditor id="docxEditor" documentServerUrl={documentServerUrl} config={this.state.config} />
            )
        }
    }

在 w 源码中调用渲染方法

{$page.renderEditor()}

1756708145097

打开页面

打开页面系统提供三种方式:打开门户页、打开对话框、打开抽屉。本文介绍前两种

打开门户页运行效果,如下图所示

1756706178724

打开对话框的运行效果,如下图所示

1756706210155

门户页

使用页面组件的 navigateTo 方法打开门户页,示例代码如下

    onEditOnlineBtnClick = ({ row }) => async (event) => {
        //保存数据,文档编辑回调服务中会修改本行数据
        await this.comp("mainData").saveData();
        //获取附件列的 JSON 对象
        let json = JSON.parse(row.files || "[]");
        if (json.length > 0) {
            let storeFileName = json[0].storeFileName;
            let realFileName = json[0].realFileName;
            //打开在线编辑页面
            this.navigateTo({
                url: this.getUIUrl("$UI/pcx/onlyoffice/editPage.w?title=在线编辑文档&storeFileName="
                    + storeFileName + "&doctitle=" + realFileName + ".docx&dataId=" + row.fid)
            });
        }
    }
对话框

在页面上添加对话框组件,页面文件属性选择文档编辑器页面,开启组件引用,如下图所示

1756706681166

在弹出层配置中,设置标题和宽度,如下图所示

1756706557099

在按钮的点击事件中,调用对话框组件的 open 方法打开对话框,示例代码如下

    onEditDialogBtnClick = ({ row }) => async (event) => {
        //保存数据,文档编辑回调服务中会修改本行数据
        await this.comp("mainData").saveData();
        //获取附件列的 JSON 对象
        let json = JSON.parse(row.files || "[]");
        if (json.length > 0) {
            let storeFileName = json[0].storeFileName;
            let realFileName = json[0].realFileName;
            //打开在线编辑页面
            this.comp("editDialog").open({
                params: {
                    storeFileName: storeFileName,
                    doctitle: realFileName,
                    dataId: row.fid
                }
            });
        }
    }

关闭页面

关闭页面时,触发页面组件的卸载事件,如下图所示

1756710787839

在卸载事件中,给父页面发送消息,以便父页面接收到消息后刷新业务数据

    onPageUnload = (event) => {
        //关闭页面给父页面发送消息
        this.getOpener().postMessage({ data: "onlyoffice-close" });
    }

父页面收到消息后,触发页面组件的接收消息事件,如下图所示

1756706798915

在接收消息事件中,首先显示遮罩,2秒后刷新业务数据,刷新后关闭遮罩,示例代码如下

    //在线编辑页面关闭后触发
    onPageMessage = (event) => {
        if (event.data == "onlyoffice-close") {
            //等2秒,刷新数据
            this.setState({ loading: { fullscreen: true } });
            window.setTimeout(async () => {
                await this.comp("mainData").refreshData();
                this.setState({ loading: false });
            }, 2000);
        }
    }

特别说明

  • 上面代码中的2秒是怎么来的?
    • 关闭 OnlyOffice 的文档编辑器5秒后,OnlyOffice 调用回调服务,在回调服务中,实现文档的下载、上传至 minIO、以及更新业务数据
    • 5秒是默认值,可调整,本例调整为1秒。即关闭文档编辑器1秒后,执行回调服务修改业务数据,2秒后前端刷新业务数据
    • 2秒是一个估算值,需要根据最终运行环境进行适当调整
  • 如果要实现在后端回调服务处理完成后,前端页面刷新业务数据,使用事件中心的消息推送实现,参考《前端消息通讯 centrifugoService

使用 html 动态加载 js

添加页面

添加一个空白页面,作为文档编辑器的页面。添加三个页面参数,如下图所示

1756461537862

添加“获取 config”服务组件,添加页面的初次渲染完成事件,如下图所示

1756711214566

在初次渲染完成事件中,加载 OnlyOffice 的 api.js 文件,调用“获取 config”服务获取 config,使用 new DocsAPI.DocEditor 初始化文档编辑器

react 代码如下

    onPageReady = (event) => {
        this.loadJs().then(() => {
            this.initEditor();
        });
    }

    loadJs = () => {
        return new Promise(function (resolve, reject) {
            if (window.DocsAPI) {
                resolve(window.DocsAPI);
                return;
            }
            let script = document.createElement("script");
            let documentServerUrl = "https://onlyoffice" + window.location.host.substr(window.location.host.indexOf(".")) + "/";
            script.src = documentServerUrl + "web-apps/apps/api/documents/api.js";
            document.head.appendChild(script);
        });
    }

    initEditor = async () => {
        //获取config
        let { data } = await this.comp("getConfigRequest").send({
            dataId: this.params.dataId,
            title: this.params.doctitle,
            storeFileName: this.params.storeFileName
        });
        window.docEditor = new DocsAPI.DocEditor("placeholder", data);
    }

vue 代码如下

let onPageReady = (event) => {
    loadJs().then(() => {
        initEditor();
    });
}

let loadJs = () => {
    return new Promise(function (resolve, reject) {
        if (window.DocsAPI) {
            resolve(window.DocsAPI);
            return;
        }
        let script = document.createElement("script");
        let documentServerUrl = "https://onlyoffice" + window.location.host.substr(window.location.host.indexOf(".")) + "/";
        script.src = documentServerUrl + "web-apps/apps/api/documents/api.js";
        document.head.appendChild(script);
    });
}

let initEditor = async () => {
    //获取config
    let { data } = await $page.comp("getConfigRequest").send({ 
        dataId: $page.params.dataId,
        title: $page.params.doctitle,
        storeFileName: $page.params.storeFileName
    });
    window.docEditor = new DocsAPI.DocEditor("placeholder", data);
}

打开页面

如果系统组件使用的是 vue 组件,参考前面“使用 vue 组件”一节中的打开页面 如果系统组件使用的是 react 组件,参考前面“使用 react 组件”一节中的打开页面

关闭页面

如果系统组件使用的是 vue 组件,参考前面“使用 vue 组件”一节中的关闭页面 如果系统组件使用的是 react 组件,参考前面“使用 react 组件”一节中的关闭页面

文档编辑器高度自适应

OnlyOffice 使用 iframe 显示,高度默认100%,即依赖外部容器的高度

在门户页中充满

页面组件设置自动充满属性为 true 即可,如下图所示

1756712284314

在对话框中充满

对话框组件的高度依赖内部组件的高度,在页面上添加区块组件,设置高度为 calc(100vh - 72px);,对话框的高度即可充满整个浏览器。文档编辑器放在这个区块中即可

1756712326124

案例位置

桌面-在线编辑文档-在线编辑.w

results matching ""

    No results matching ""