全部產品
Search
文件中心

Intelligent Media Management:快速入門

更新時間:Nov 05, 2024

本文介紹文檔線上協作的功能特性、實現原理和使用方法等。

功能特性

文檔線上協作支援多人即時線上預覽或編輯同一個文檔,文檔多人協作,效率更高。其功能特性如下:

  • 更新內容即時同步,自動儲存,避免出現文檔內容丟失的情況。

  • 即時儲存歷史版本,您可以將文檔恢複到指定的歷史版本。

  • 應用覆蓋全終端,手機、電腦、網頁均可使用。

  • 上手門檻低,會使用Office辦公軟體操作即可使用文檔線上協作。

  • 支援多種類型的文檔預覽或編輯。

    • 支援預覽的輸入檔案格式:

      • 文字文檔(Word):doc、dot、wps、wpt、docx、dotx、docm、dotm、rtf。

      • 示範文檔(PPT):ppt、pptx、pptm、ppsx、ppsm、pps、potx、potm、dpt、dps。

      • 表格文檔(Excel):xls、xlt、et、xlsx、xltx、csv、xlsm、xltm。

      • PDF檔案(PDF):pdf。

    • 支援編輯的輸入檔案格式:

      • 文字文檔(Word):doc、dot、wps、wpt、docx、dotx、docm、dotm。

      • 示範文檔(PPT):ppt、pptx、pptm、ppsx、ppsm、pps、potx、potm、dpt、dps。

      • 表格文檔(Excel):xls、xlt、et、xlsx、xltx、xlsm、xltm。

  • 文檔協作時支援自訂配置,包括配置組件狀態、事件、文字相關、表格相關等。

  • 文檔預覽和編輯支援的文檔格式詳細內容請參見文檔限制

  • 若您不需要線上預覽的方式,即文檔在預覽時無協作線上編輯,或預覽時不需要更新協作線上編輯內容,可以選擇緩衝預覽方式。緩衝預覽滿足普通情境下的預覽需求,設定開啟緩衝預覽後,不會在預覽時重新整理線上編輯產生的文檔變化內容。更多關於緩衝預覽的設定方式,請查看API文檔

實現原理

要對接IMM的WebOffice服務,您的Web應用需要同時修改服務端和前端代碼。

首先確保原始文檔在OSS上,前端調用服務端封裝的介面,擷取文檔的協作地址和AccessToken,然後調用js-sdk初始化(會在指定塊元素下動態產生iframe),並設定AccessToken實現文檔預覽或編輯。

p100109

前提條件

  1. 已建立並擷取AccessKey。具體操作,請參見擷取AccessKey

  2. 已開通OSS服務、建立儲存空間並上傳文檔到儲存空間。具體操作,請參見上傳檔案

  3. 已開通Intelligent Media Management服務。具體操作,請參見開通產品

  4. 已通過Intelligent Media Management控制台建立專案。具體操作,請參見建立專案

    說明
  5. 當訪問的OSS Bucket網域名稱與預覽引擎的網域名稱不同時,需要在OSS控制台將預覽服務網域名稱添加到儲存文檔的OSS Bucket的跨域訪問列表中。具體操作,請參見設定跨域訪問

注意事項

使用方法

步驟一:服務端封裝介面

在服務端分別封裝GenerateWebofficeToken - 擷取Weboffice憑證RefreshWebofficeToken - 重新整理Weboffice憑證介面,用於擷取編輯地址和AccessToken,方便前端直接調用。如下以專案名稱為test-project,OSS檔案地址為oss://test-bucket/test-object.docx為例,介紹封裝介面的操作步驟。

  1. 調用GenerateWebofficeToken - 擷取Weboffice憑證介面,擷取協作地址。

    • 請求樣本

      {
          "ProjectName": "test-project", //IMM專案名稱。
          "SourceURI": "oss://test-bucket/test-object.docx", //OSS檔案URI。
          "Filename": "test-object.docx", //檔案名稱。
          "UserData": "{\"fid\": \"123\"}", //使用者資料,會在MNS通知中原樣返回。
          "PreviewPages": 3, //預覽的頁數。
          "Permission": "{\"Rename\": \"true\", \"Readonly\": \"false\"}", //設定許可權。
          "User": "{\"Id\": \"test\", \"Name\": \"testuser\", \"Avatar\": \"http://xx.com/avatar.jpg\"}", //線上協作顯示的使用者資訊。
          "Watermark": "{\"Type\": \"1\", \"Value\": \"imm\"}" //設定浮水印。
      }
    • 返回樣本

      {
          "RefreshToken": "f1fd1afd79ee445f95d3dd99f34f35ffv3",
          "RequestId": "BC63D209-5E53-00E9-8D24-7043943DBC89",
          "AccessToken": "3de242da81e1433abefbbea000aaae39v3",
          "RefreshTokenExpiredTime": "2022-07-06T23:18:52.856132358Z",
          "WebofficeURL": "https://office-cn-shanghai.imm.aliyuncs.com/office/w/7c1a7b53d6a4002751ac4bbaea69405a01475f4a?_w_tokentype=1",
          "AccessTokenExpiredTime": "2022-07-05T23:48:52.856132358Z"
      }
    • 完整範例程式碼(以1.27.3版本Python SDK為例)

      # -*- coding: utf-8 -*-
      import os
      from alibabacloud_imm20200930.client import Client as imm20200930Client
      from alibabacloud_tea_openapi import models as open_api_models
      from alibabacloud_imm20200930 import models as imm_20200930_models
      from alibabacloud_tea_util import models as util_models
      from alibabacloud_tea_util.client import Client as UtilClient
      
      
      class Sample:
          def __init__(self):
              pass
      
          @staticmethod
          def create_client(
              access_key_id: str,
              access_key_secret: str,
          ) -> imm20200930Client:
              """
              使用AccessKey ID和AccessKey Secret初始化帳號Client。
              @param access_key_id:
              @param access_key_secret:
              @return: Client
              @throws Exception
              """
              config = open_api_models.Config(
                  access_key_id=access_key_id,
                  access_key_secret=access_key_secret
              )
              #填寫訪問網域名稱。
              config.endpoint = f'imm.cn-shenzhen.aliyuncs.com'
              return imm20200930Client(config)
      
          @staticmethod
          def main() -> None:
              # 阿里雲帳號AccessKey擁有所有API的存取權限,建議您使用RAM使用者進行API訪問或日常營運。
              # 強烈建議不要把AccessKey ID和AccessKey Secret儲存到工程代碼裡,否則可能導致AccessKey泄露,威脅您帳號下所有資源的安全。
              # 本樣本通過從環境變數中讀取AccessKey,來實現API訪問的身分識別驗證。如何配置環境變數,請參見https://www.alibabacloud.com/help/document_detail/2361894.html。
              imm_access_key_id = os.getenv("AccessKeyId")
              imm_access_key_secret = os.getenv("AccessKeySecret")
              client = Sample.create_client(imm_access_key_id, imm_access_key_secret)
              #設定浮水印。
              weboffice_watermark = imm_20200930_models.WebofficeWatermark(
                  type=1,
                  value='imm'
              )
              #填寫協作使用者資訊。
              weboffice_user = imm_20200930_models.WebofficeUser(
                  id='test',
                  name='testuser',
                  avatar='http://xx.com/avatar.jpg'
              )
              #設定許可權。
              weboffice_permission = imm_20200930_models.WebofficePermission(
                  rename=True
              )
              get_weboffice_urlrequest = imm_20200930_models.GenerateWebofficeTokenRequest(
                  #填寫IMM專案名稱。
                  project_name='test-project',
                  #填寫協作的檔案URI。
                  source_uri='oss://test-bucket/test-object.docx',
                  #填寫檔案名稱。
                  filename='test-object.docx',
                  #填寫使用者資料。
                  user_data='{"fid": "123"}',
                  preview_pages=3,
                  external_uploaded=False,
                  permission=weboffice_permission,
                  user=weboffice_user,
                  watermark=weboffice_watermark
              )
              runtime = util_models.RuntimeOptions()
              try:
                  #列印API的傳回值。
                  response = client.get_weboffice_urlwith_options(get_weboffice_urlrequest, runtime)
                  print(response.body.to_map())
              except Exception as error:
                  #如有需要,請列印錯誤資訊。
                  UtilClient.assert_as_string(error.message)
                  print(error)
      
      
      if __name__ == '__main__':
          Sample.main()
  2. 調用RefreshWebofficeToken - 重新整理Weboffice憑證介面,重新整理AccessToken。

    AccessToken具有時效性,當到期後前端需要調用服務端RefreshWebofficeToken介面重新重新整理AccessToken,所以需要在服務端封裝此介面。調用此介面的返回結果格式和調用GenerateWebofficeToken介面的相同。

步驟二:前端JS-SDK使用

通過JS-SDK將返回的預覽地址掛載到HTML塊狀元素中並設定AccessToken。

  1. 引入JS-SDK。

    樣本中的${x.y.z}表示JS-SDK的最新版本號碼,請根據實際填寫,最新版本請參見JS-SDK版本

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Demo</title>
    </head>
    <body>
      <script src="https://g.alicdn.com/IMM/office-js/${x.y.z}/aliyun-web-office-sdk.min.js"></script>
      <script>
        console.log('引入後可以開始使用JS-SDK了!');
        console.log(aliyun); //全域變數名。
      </script>
    </body>
    </html>
  2. 初始化。

    通過在服務端封裝的GenerateWebofficeToken介面擷取tokenInfo對象。

    假設tokenInfo對象和調用GenerateWebofficeToken介面返回的結構一致。如下代碼以服務端封裝的GenerateWebofficeToken介面為/getTokenInfo為例。

    //擷取協作地址和AccessToken。
    var tokenInfo = await $.get('http://example.com/getTokenInfo')
    
    // 初始化
    let instance = aliyun.config({
      url: tokenInfo.WebofficeURL //設定文檔協作URL地址。
    })
  3. 自訂Office(iframe)掛載點。

    說明

    DOMContentLoaded事件被觸發後,請確保掛載節點存在再執行初始化操作。

    iframe 預設會掛載到body下,您可以根據需要自訂iframe 的掛載點。

    <div id="container"></div>
    let instance = aliyun.config({
      mount: document.querySelector('#container'),
      url: '文檔協作URL地址' //即步驟2樣本中的文檔協作URL地址(tokenInfo.WebofficeURL)。
    })

    如果需要對iframe對象做特殊處理,可以通過JS-SDK執行個體化對象快速擷取到iframe的DOM(Document Object Model)對象。

    var instance = aliyun.config({
        mount: document.querySelector('#container')
       //...
    })
    console.log(instance.iframe)
  4. 設定令牌(Token)。

    重要
    • 2023-05-01之前建立的專案使用WebOffice進行文檔預覽和線上協作按預覽開啟次數計費,開啟一次記一次。

    • 2023-05-01之後建立的專案使用WebOffice進行文檔預覽和線上協作按介面調用次數計費,調用GenerateWebofficeTokenRefreshWebofficeToken介面時進行計費。

    • JS-SDK會提前5分鐘調用RefreshWebofficeToken介面重新整理Token方法,所以設定的timeout應在20分鐘以上(20 * 60 * 1000以上,單位為毫秒),token有效期間預設30分鐘,避免重新整理Token過快產生額外費用。

    • 在擷取協作地址後,需要設定令牌才能線上協作。

    • 每次重新整理權杖後,也需要通過此方法設定令牌。

    // https://www.alibabacloud.com/help/document_detail/611302.htm?spm=a2c4g.478147.0.0.794d5d6dqtWTzI
    //根據業務需求通過非同步請求或者模板輸出的方式擷取Token。
    var token = 'yourToken'; 
    //設定Token。
    instance.setToken({
      token: token, 
      timeout: 25 * 60 * 1000, // 必須設定,Token逾時時間,單位為ms,樣本設定逾時時間為25分鐘。可配合refreshToken配置函數使用,在逾時前5分鐘調用refreshToken重新重新整理Token。
    }) 
  5. 逾時更新令牌(Token)。

    通過在服務端封裝的RefreshWebofficeToken介面擷取tokenInfo對象。假設tokenInfo對象和調用RefreshWebofficeToken介面返回的結構一致。

    您可以通過傳入擷取Token的函數,在Token逾時時,JS-SDK會自動調用傳入的函數重新擷取Token,返回一個promise或者object。

    如下樣本以服務端封裝的GetWebofficeToken介面為/refreshTokenInfo為例。

    //緩衝上次的tokenInfo,用於重新整理Token。
      let lastTokenInfo = tokenInfo
    
    //擷取Token函數。
    //注意:refreshToken目前不支援async, 只支援返回Promise或者{token,timeout}對象。
      const refreshToken = function() {
        return new Promise(function(resolve){
          //業務處理邏輯,調用服務端封裝的refreshToken介面。
          $.get('http://example.com/refreshTokenInfo',{
            RefreshToken: lastTokenInfo.RefreshToken,
            AccessToken: lastTokenInfo.AccessToken,
            //....
          }).then(function(tokenInfo){
            lastTokenInfo = tokenInfo
            resolve({
              token: tokenInfo.AccessToken, //必須設定。
              timeout: 25 * 60 * 1000, // 必須設定,Token逾時時間,單位為ms,樣本設定逾時時間為25分鐘。可配合refreshToken配置函數使用,在逾時前5分鐘調用refreshToken重新重新整理Token。
            })
          })
        })
      }
    //配置逾時擷取Token函數。
    aliyun.config({
      //...
      refreshToken
    })

範例程式碼

JS-SDK文檔預覽完整樣本如下。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Demo</title>
  <meta name="viewport" content="width=device-width,initial-scale=1.0"> 
  <style>
    html,body{
      margin:0;
      height:100%;
    }
    #container{ 
      height: 100%;
      width: 100%; 
    }
    iframe {
      width: 100% !important;
      height: 100% !important;
    }
  </style>
</head>
<body>
  <script src="https://g.alicdn.com/IMM/office-js/1.1.19/aliyun-web-office-sdk.min.js"></script>
  <div id="container"></div>
  <script>
    window.onload = init;
    async function init() {
      preview(
        //GenerateWebofficeToken返回的預覽Token資訊。
        {
            "RefreshToken": "f1fd1afd79ee445f95d3dd99f34f35ffv3",
            "RequestId": "BC63D209-5E53-00E9-8D24-7043943DBC89",
            "AccessToken": "3de242da81e1433abefbbea000aaae39v3",
            "RefreshTokenExpiredTime": "2022-07-06T23:18:52.856132358Z",
            "WebofficeURL": "https://office-cn-shanghai.imm.aliyuncs.com/office/w/7c1a7b53d6a4002751ac4bbaea69405a01475f4a?_w_tokentype=1",
            "AccessTokenExpiredTime": "2022-07-05T23:48:52.856132358Z"
        }

      )
    }
    
    function preview(tokenInfo) {
      let mount = document.querySelector('#container');
      let instance = aliyun.config({
        mount,
        url: tokenInfo.PreviewURL || tokenInfo.EditURL || tokenInfo.WebofficeURL,
        mode: 'normal',
        // refreshToken
      });
      instance.setToken({ token: tokenInfo.AccessToken, timeout: 25 * 60 * 1000 });

      instance.on('fileOpen', function(data) {
        console.log(data);
      });

      instance.on('error', (err) => {
        console.log('發生錯誤:', err);
      });

    }
  </script>
</body>
</html>