使用 ONLYOFFICE 轉(zhuǎn)換 API 構(gòu)建在線文檔轉(zhuǎn)換器

文檔轉(zhuǎn)換是非常常用、非常有價(jià)值的功能,可以幫助我們處理多種文檔類型。ONLYOFFICE 編輯器可以輕松地將文檔轉(zhuǎn)換為多種格式。在這篇博文中,我們會向您展示,如何構(gòu)建在 ONLYOFFICE 轉(zhuǎn)換 API 上運(yùn)行的在線轉(zhuǎn)換器。


關(guān)于 ONLYOFFICE 轉(zhuǎn)換 API

使用文檔轉(zhuǎn)換服務(wù),您可就各種類型的 Office 文檔做轉(zhuǎn)換:文本、表格、幻燈片、表單、PDF 和電子書。它幫助您基于文檔和表格創(chuàng)建 PDF,將教科書轉(zhuǎn)換為電子書,將演示文稿轉(zhuǎn)換為圖片文件,等等。ONLYOFFICE 支持 50 多種文件類型。

操作方法

我們的轉(zhuǎn)換 API 通過“文檔轉(zhuǎn)換服務(wù)”運(yùn)行。它是 ONLYOFFICE 文檔服務(wù)器的一部分,支持我們將各種文檔文件轉(zhuǎn)換為合適的格式。

轉(zhuǎn)換要分幾個(gè)步驟進(jìn)行:

  1. 用戶選擇一個(gè)要上傳到“文檔管理器”的文件。
  2. “文檔管理器”將選定的文件上傳到“文檔存儲服務(wù)”。
  3. “文檔存儲服務(wù)”通過使用“轉(zhuǎn)化 API”將上傳的文件發(fā)送到“文檔轉(zhuǎn)換服務(wù)”。
  4. “文檔轉(zhuǎn)換服務(wù)”將選定的文件轉(zhuǎn)換為目標(biāo)格式。
  5. “文檔存儲服務(wù)”下載轉(zhuǎn)換后的文檔文件。

“文檔管理器”和“文檔存儲服務(wù)”是客戶端和服務(wù)器端的工具,方便選擇和存儲文檔供進(jìn)一步轉(zhuǎn)換。不過,我們的 web 應(yīng)用會處理這些任務(wù),這得益于我們正在構(gòu)建的自定義轉(zhuǎn)換器。

前提條件

我們的轉(zhuǎn)換器基于 NodeJS。因此,對于這個(gè)項(xiàng)目,我們需要如下條件:

我們會使用 Axios 包向 ONLYOFFICE 文檔服務(wù)器發(fā)送一個(gè) post 請求,并使用 Jsonwebtoken 包簽署一個(gè) JWT 令牌。從版本 7.2 開始,JWT 認(rèn)證默認(rèn)處于啟用狀態(tài)。

或者,您還可以通過另一個(gè)選項(xiàng),在 JWT 認(rèn)證停用的情況下運(yùn)行 ONLYOFFICE 文檔服務(wù)器鏡像。為此,請?jiān)诮K端執(zhí)行如下命令:

sudo docker run -i -t -d -p 80:80 -e JWT_ENABLED=false onlyoffice/documentserver

我們的轉(zhuǎn)換器向 ONLYOFFICE 文檔服務(wù)器發(fā)送的“post 請求”如下:

{
        "async": true,
        "filetype": fileType,
        "key": key, 
        "outputtype": outputType,
        "title": `Converted Document.${outputType}`,
        "url": link      
    }
  • 在“accept”參數(shù)中,我們指定要接收 JSON 格式的響應(yīng)。
  • “async”參數(shù)指示該請求是異步請求。
  • “fileType”參數(shù)指定我們要轉(zhuǎn)換的原始文件的類型。
  • “key”參數(shù)指定當(dāng)前文件的唯一標(biāo)識符 (UID)。
  • “outputType”參數(shù)指定轉(zhuǎn)換后的文件的格式。
  • “title”參數(shù)包含轉(zhuǎn)換后的文檔的名稱。
  • “url”參數(shù)包含指向我們要轉(zhuǎn)換的文件的鏈接。

“fileType”、“outputType”和“url”參數(shù)的值是從我們應(yīng)用的客戶端獲取,存儲在變量中?!発ey”參數(shù)的值也是隨機(jī)生成,存儲在變量中。

項(xiàng)目設(shè)置

將所需的包安裝好后,我們前往“app.js”文件,將它們與“bodyParser”一起初始化,以處理“post 請求”數(shù)據(jù)。我們還創(chuàng)建了一個(gè)公開文件夾和一個(gè)視圖引擎:

const express = require('express');
const app = express();
const axios = require('axios'); 
const jwt = require('jsonwebtoken');
 
 
app.use(express.urlencoded({extended: true}));
app.use(express.json());
app.use(express.static("public"));
app.set('view engine', 'ejs');

然后我們添加路由。我們的應(yīng)用會包含一個(gè)“get”路由和一個(gè)“post”路由。我們可以使用它們來獲取輸入數(shù)據(jù),并將數(shù)據(jù)傳遞到 ONLYOFFICE 文檔服務(wù)器的“post 請求”中:

app.get ('/', function (reg, response){ 
}
 
app.post ('/converter', function(req, response){
}

客戶端

現(xiàn)在我們花點(diǎn)時(shí)間,看看轉(zhuǎn)換器的客戶端。就是在這里,我們要輸入所有所需數(shù)據(jù):


客戶端包括兩個(gè) EJS 頁面:

  • homepage.ejs:我們在這里提取“post 請求”所需的所有值。
  • converter.ejs:我們在這里下載轉(zhuǎn)換后的文件。

我們來詳細(xì)看看“homepage.ejs”。這里我們創(chuàng)建了一個(gè)表單,將數(shù)據(jù)發(fā)送到“post”路由。首先,我們獲得一個(gè)原始文件的URL。我們將把其存儲在服務(wù)器端的“l(fā)ink”變量中:

<h1 class="h3 mb-3 font-weight-normal">Convert your OOXML files here!</h1>
        <input type="text"  class="form-control" id="inputEmail" placeholder="Paste a link to the file" name="link" onchange="activateBox()">

然后我們在組合框中選一個(gè)原始文件的類型。之后,我們提取這個(gè)值,并將其存儲在“inputType”變量中:

<select class="form-control" id="inputType" input type="text" disabled="true" name="inputType" onchange="comboBox()">
          <option value="" selected>Input File Type</option>
          <option value="docx">docx</option>
          <option value="txt">txt</option>
          <option value="pdf">pdf</option>
          <option value="rtf">rtf</option>
          <option value="xml">xml</option>
          <option value="csv">csv</option>
          <option value="xlsx">xlsx</option>
          <option value="xls">xls</option>
          <option value="ppt">ppt</option>
          <option value="pptx">pptx</option>
</select>

然后,我們選擇所需的文件類型。這個(gè)值會被儲存在服務(wù)器端的“outputType”變量中:

<select class="form-control" id="outputType" input type="text" disabled="true" name="outputType" onchange="activateButton()">
      <option value="" disabled selected hidden>Output File Type</option>
    </select>

我們用一個(gè)按鈕將所有數(shù)據(jù)發(fā)送到“轉(zhuǎn)換器”post 路由:

<div class="button">
      <button type="submit" id="download" disabled="true" class="btn btn-lg btn-primary btn-block">Convert</button>
    </div>
    </form>

構(gòu)建轉(zhuǎn)換器

提取的數(shù)據(jù)會在我們應(yīng)用的服務(wù)器端進(jìn)行解析?,F(xiàn)在,我們前往“app.js”文件去獲?。?/p>

app.post ('/converter', function(req, response){
    let link = req.body.link;
    let outputType = req.body.outputType;
    let fileType = req.body.inputType;
 
});

現(xiàn)在我們看看第二個(gè)組合框,它將“outputType”值發(fā)送到“post”路由:

  <select class="form-control" id="outputType" input type="text" disabled="true" name="outputType" onchange="activateButton()">
      <option value="" disabled selected hidden>Output File Type</option>
    </select>

“outputType”變量包含在對服務(wù)器的“post 請求”中。它指定轉(zhuǎn)換后的文件的格式。我們來看看支持我們與頁面元素互動的 JavaScript 代碼,并將動態(tài)列表并入我們的用戶界面。

“文檔轉(zhuǎn)換服務(wù)”是一個(gè)非常強(qiáng)大的工具,能夠轉(zhuǎn)換各種類型的文件。所以我們的目標(biāo)是利用一個(gè)動態(tài)列表,讓我們?yōu)檗D(zhuǎn)換后的文件選擇一種格式。這個(gè)列表會顯示針對特定類型的原始文件的所有可用選項(xiàng)。

為此,我們創(chuàng)建一個(gè) JSON 文件,按照每個(gè)特定的類型來存儲數(shù)值:

請注意!在示范中,我們只列出了最常用的 OOXML 格式。如要了解所有受支持的轉(zhuǎn)換選項(xiàng),請?jiān)L問我們的文檔頁面。
然后我們添加一個(gè)函數(shù)來生成這個(gè)動態(tài)列表:

function comboBox () {
     let type = document.querySelector("#inputType").value;
     let listDropDown = document.querySelector("#outputType");
     fetch("formats.json")
    .then(function(response){
      return response.json();
    })
    .then(function(data){
     let options = data[type];
     let out = "";
     out += `<option value="">Output File Type</option>`;
     Object.values(options).map(function(format){
        out += '<option value=' + format + '>' + format + '</option>';
      });
     listDropDown.innerHTML = out;
     listDropDown.disabled = false;
               });  
    };
        };

首先,這個(gè)函數(shù)獲取“inputType”組合框的值,我們在這里選擇原始文件的格式。我們把它分配給“type”變量,以便在后面使用這個(gè)值。然后我們發(fā)出一個(gè) AJAX 請求來加載 JSON 數(shù)據(jù)。之后,我們使用“type”變量的值作為索引,迭代加載的數(shù)據(jù),將其值插入下拉列表的選項(xiàng)中。

現(xiàn)在,我們每次選擇原始文件的類型時(shí),腳本就會執(zhí)行,并按照原始文件格式向我們顯示可用的轉(zhuǎn)換選項(xiàng)。
而在我們得到所有需要的數(shù)據(jù)后,點(diǎn)擊“轉(zhuǎn)換”按鈕即可將其發(fā)送到轉(zhuǎn)換器路由。

但實(shí)際不是這樣。為了讓我們的應(yīng)用更具互動性,我們會添加函數(shù),以正確的順序激活組合框和按鈕元素:

 function activateBox() {
      $("#inputType").prop('disabled', false)
    };
    
    function activateButton() {
      $("#download").prop('disabled', false)
      $("#outputTypeForm").hide();
    };

完整的 JavaScript 代碼如下:

     function comboBox () {
     let type = document.querySelector("#inputType").value;
     let listDropDown = document.querySelector("#outputType");
     fetch("formats.json")
    .then(function(response){
      return response.json();
    })
    .then(function(data){
     let options = data[type];
     let out = "";
     out += `<option value="">Output File Type</option>`;
     Object.values(options).map(function(format){
        out += '<option value=' + format + '>' + format + '</option>';
      });
     listDropDown.innerHTML = out;
     listDropDown.disabled = false;
               });  
    };
    function activateBox() {
      $("#inputType").prop('disabled', false)
    };
    
    function activateButton() {
      $("#download").prop('disabled', false)
      $("#outputTypeForm").hide();
    };
        }

我們來看看服務(wù)器端的狀態(tài):

app.post ('/converter', function(req, response){
    let link = req.body.link;
    let outputType = req.body.outputType;
    let fileType = req.body.inputType;
    let key =  function () {
        var key = '';
        var str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + 
                'abcdefghijklmnopqrstuvwxyz0123456789';
          
        for (let i = 1; i <= 12; i++) {
            var char = Math.floor(Math.random()
                        * str.length + 1);
              
            key += str.charAt(char);
        }
          
        return key;
    };
    const payload =  { 
        "async": true,
        "filetype": fileType,
        "key": key, 
        "outputtype": outputType,
        "title": `Converted Document.${outputType}`,
        "url": link       
    }
    let token = jwt.sign(payload, secret, options);
    
    axios.post( 
        'http://127.0.0.1:83/ConvertService.ashx',
        { 
           "token": token
        }) 
        .then((res) => response.render('converter.ejs', {
            link: res.data.fileUrl
        })) 
});

在“converter”路由中,我們生成了針對 ONLYOFFICE 文檔服務(wù)器的 post 請求,并將其存儲在“payload”變量中。我們使用了“fileType”、“outputType”和“l(fā)ink”變量,我們提取的數(shù)據(jù)也是存儲在這些變量中。然而,我們還有一個(gè)“key”變量,包含當(dāng)前文檔的唯一標(biāo)識符。所以我們在上面添加了一個(gè)小函數(shù)來將其生成:

    let key =  function () {
        var key = '';
        var str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + 
                'abcdefghijklmnopqrstuvwxyz0123456789';
          
        for (let i = 1; i <= 12; i++) {
            var char = Math.floor(Math.random()
                        * str.length + 1);
              
            key += str.charAt(char)
        }   
        return key;
    };

現(xiàn)在,所有關(guān)于請求的必要的值都齊備了,我們用 jwt.sign 把它們封裝在一個(gè)令牌中:

  let token = jwt.sign(payload, secret, options);

“jwt.sign”方法需要三個(gè)參數(shù):

  • Payload:包括成功轉(zhuǎn)換所需的所有參數(shù)。
  • Header:包含加密算法和過期時(shí)間范圍相關(guān)信息。我們將這些參數(shù)封裝在選項(xiàng)變量中。
  • Secret:代表 ONLYOFFICE 文檔服務(wù)器生成的密鑰。您可以在 local.json 文件中找到這個(gè)密鑰,或者通過在終端執(zhí)行如下命令:
sudo docker exec <dockerID> /var/www/onlyoffice/documentserver/npm/json -f /etc/onlyoffice/documentserver/local.json 'services.CoAuthoring.secret.session.string'

在簽署了令牌之后,我們再使用一個(gè)“axios post request”將其發(fā)送到服務(wù)器。然后我們呈現(xiàn)“converter.ejs”頁面,該頁面從 ONLYOFFICE 文檔服務(wù)器接收響應(yīng):

 axios.post( 
        'http://127.0.0.1:83/ConvertService.ashx',
        { 
           "token": token
        }) 
        .then((res) => response.render('converter.ejs', {
            link: res.data.fileUrl
        }))

這是 JSON 格式響應(yīng)的樣本:

{     "endConvert": true,     "fileType": "docx",     "fileUrl": "https://documentserver/url-to-converted-document.pdf",     "percent": 100 }

這里需要“fileUrl”元素,是指向轉(zhuǎn)換后的文件的鏈接。所以我們要獲取它,并將其發(fā)送到“converter.ejs”頁面:

.then((res) => response.render('converter.ejs', {
            link: res.data.fileUrl
        })) 
});

在該頁面,我們創(chuàng)建兩個(gè)按鈕?!胺祷亍卑粹o可讓我們回到 homepage.ejs 頁面;“下載”按鈕則打開我們發(fā)送到該頁面的鏈接,并下載轉(zhuǎn)換后的文件:


請注意!如需詳細(xì)了解 JWT,請?jiān)L問我們的文檔頁面。

服務(wù)器端完整代碼如下:

const express = require('express');
const app = express();
const axios = require('axios'); 
const jwt = require('jsonwebtoken');
const options = {algorithm: "HS256", expiresIn: "5m"};
const secret = "k1gWQdmDX6ZGiWw5r3g2";
app.use(express.urlencoded({extended: true}));
app.use(express.json());
app.use(express.static("public"));
app.set('view engine', 'ejs');
app.get ('/', function (reg, response){ 
    response.render('homepage.ejs', {
    })
});
app.post ('/converter', function(req, response){
    let link = req.body.link;
    let outputType = req.body.outputType;
    let fileType = req.body.inputType;
    let key =  function () {
        var key = '';
        var str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + 
                'abcdefghijklmnopqrstuvwxyz0123456789';
          
        for (let i = 1; i <= 12; i++) {
            var char = Math.floor(Math.random()
                        * str.length + 1);
              
            key += str.charAt(char);
        }
          
        return key;
    };
    const payload =  { 
        "async": true,
        "filetype": fileType,
        "key": key, 
        "outputtype": outputType,
        "title": `Converted Document.${outputType}`,
        "url": link       
    }
    let token = jwt.sign(payload, secret, options);
    
    axios.post( 
        'http://127.0.0.1:83/ConvertService.ashx',
        { 
           "token": token
        }) 
        .then((res) => response.render('converter.ejs', {
            link: res.data.fileUrl
        })) 
});
app.listen(3000,() => console.log('the server is up and running'));

現(xiàn)在,我們來運(yùn)行轉(zhuǎn)換器,了解如何使用!

ONLYOFFICE 解決方案的功能非常豐富。這些解決方案為用戶和開發(fā)者提供獨(dú)特體驗(yàn),讓他們能夠以多種方式操作 ooXML 文檔。我們希望您覺得如上提到的信息很有用,并將其應(yīng)用在您未來的項(xiàng)目中。歡迎您發(fā)表評論、提出問題或與我們分享您的想法,我們樂意接受建議、展開合作。祝您的探索一切順利!

相關(guān)鏈接

ONLYOFFICE 文檔服務(wù)器

轉(zhuǎn)換 API 文檔

詳細(xì)了解 JWT

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容