北京最好的網站建設公司全國疫情高峰感染高峰進度
文檔轉換是非常常用、非常有價值的功能,可以幫助我們處理多種文檔類型。ONLYOFFICE 編輯器可以輕松地將文檔轉換為多種格式。在這篇博文中,我們會向您展示,如何構建在 ONLYOFFICE 轉換 API 上運行的在線轉換器。

關于 ONLYOFFICE 轉換 API
使用文檔轉換服務,您可就各種類型的 Office 文檔做轉換:文本、表格、幻燈片、表單、PDF 和電子書。它幫助您基于文檔和表格創(chuàng)建 PDF,將教科書轉換為電子書,將演示文稿轉換為圖片文件,等等。ONLYOFFICE 支持 50 多種文件類型。
操作方法
我們的轉換 API 通過“文檔轉換服務”運行。它是 ONLYOFFICE 文檔服務器的一部分,支持我們將各種文檔文件轉換為合適的格式。
轉換要分幾個步驟進行:
- 用戶選擇一個要上傳到“文檔管理器”的文件。
- “文檔管理器”將選定的文件上傳到“文檔存儲服務”。
- “文檔存儲服務”通過使用“轉化 API”將上傳的文件發(fā)送到“文檔轉換服務”。
- “文檔轉換服務”將選定的文件轉換為目標格式。
- “文檔存儲服務”下載轉換后的文檔文件。

“文檔管理器”和“文檔存儲服務”是客戶端和服務器端的工具,方便選擇和存儲文檔供進一步轉換。不過,我們的 web 應用會處理這些任務,這得益于我們正在構建的自定義轉換器。
前提條件
我們的轉換器基于 NodeJS。因此,對于這個項目,我們需要如下條件:
- ONLYOFFICE 文檔服務器
- 安裝了如下軟件包的 NodeJS 應用:
– Express
– Axios
– Jsonwebtoken
我們會使用 Axios 包向 ONLYOFFICE 文檔服務器發(fā)送一個 post 請求,并使用 Jsonwebtoken 包簽署一個 JWT 令牌。從版本 7.2 開始,JWT 認證默認處于啟用狀態(tài)。
或者,您還可以通過另一個選項,在 JWT 認證停用的情況下運行 ONLYOFFICE 文檔服務器鏡像。為此,請在終端執(zhí)行如下命令:
sudo docker run -i -t -d -p 80:80 -e JWT_ENABLED=false onlyoffice/documentserver
我們的轉換器向 ONLYOFFICE 文檔服務器發(fā)送的“post 請求”如下:
{"async": true,"filetype": fileType,"key": key, "outputtype": outputType,"title": `Converted Document.${outputType}`,"url": link }
- 在“accept”參數中,我們指定要接收 JSON 格式的響應。
- “async”參數指示該請求是異步請求。
- “fileType”參數指定我們要轉換的原始文件的類型。
- “key”參數指定當前文件的唯一標識符 (UID)。
- “outputType”參數指定轉換后的文件的格式。
- “title”參數包含轉換后的文檔的名稱。
- “url”參數包含指向我們要轉換的文件的鏈接。
“fileType”、“outputType”和“url”參數的值是從我們應用的客戶端獲取,存儲在變量中?!発ey”參數的值也是隨機生成,存儲在變量中。
項目設置
將所需的包安裝好后,我們前往“app.js”文件,將它們與“bodyParser”一起初始化,以處理“post 請求”數據。我們還創(chuàng)建了一個公開文件夾和一個視圖引擎:
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');
然后我們添加路由。我們的應用會包含一個“get”路由和一個“post”路由。我們可以使用它們來獲取輸入數據,并將數據傳遞到 ONLYOFFICE 文檔服務器的“post 請求”中:
app.get ('/', function (reg, response){
}app.post ('/converter', function(req, response){
}
客戶端
現(xiàn)在我們花點時間,看看轉換器的客戶端。就是在這里,我們要輸入所有所需數據:


客戶端包括兩個 EJS 頁面:
- homepage.ejs:我們在這里提取“post 請求”所需的所有值。
- converter.ejs:我們在這里下載轉換后的文件。
我們來詳細看看“homepage.ejs”。這里我們創(chuàng)建了一個表單,將數據發(fā)送到“post”路由。首先,我們獲得一個原始文件的URL。我們將把其存儲在服務器端的“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()">
然后我們在組合框中選一個原始文件的類型。之后,我們提取這個值,并將其存儲在“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>
然后,我們選擇所需的文件類型。這個值會被儲存在服務器端的“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>
我們用一個按鈕將所有數據發(fā)送到“轉換器”post 路由:
<div class="button"><button type="submit" id="download" disabled="true" class="btn btn-lg btn-primary btn-block">Convert</button></div></form>
構建轉換器
提取的數據會在我們應用的服務器端進行解析?,F(xiàn)在,我們前往“app.js”文件去獲取:
app.post ('/converter', function(req, response){let link = req.body.link;let outputType = req.body.outputType;let fileType = req.body.inputType;});
現(xiàn)在我們看看第二個組合框,它將“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”變量包含在對服務器的“post 請求”中。它指定轉換后的文件的格式。我們來看看支持我們與頁面元素互動的 JavaScript 代碼,并將動態(tài)列表并入我們的用戶界面。
“文檔轉換服務”是一個非常強大的工具,能夠轉換各種類型的文件。所以我們的目標是利用一個動態(tài)列表,讓我們?yōu)檗D換后的文件選擇一種格式。這個列表會顯示針對特定類型的原始文件的所有可用選項。
為此,我們創(chuàng)建一個 JSON 文件,按照每個特定的類型來存儲數值:

請注意!在示范中,我們只列出了最常用的 OOXML 格式。如要了解所有受支持的轉換選項,請訪問我們的文檔頁面。
然后我們添加一個函數來生成這個動態(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;}); };};
首先,這個函數獲取“inputType”組合框的值,我們在這里選擇原始文件的格式。我們把它分配給“type”變量,以便在后面使用這個值。然后我們發(fā)出一個 AJAX 請求來加載 JSON 數據。之后,我們使用“type”變量的值作為索引,迭代加載的數據,將其值插入下拉列表的選項中。
現(xiàn)在,我們每次選擇原始文件的類型時,腳本就會執(zhí)行,并按照原始文件格式向我們顯示可用的轉換選項。
而在我們得到所有需要的數據后,點擊“轉換”按鈕即可將其發(fā)送到轉換器路由。
但實際不是這樣。為了讓我們的應用更具互動性,我們會添加函數,以正確的順序激活組合框和按鈕元素:
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();};}
我們來看看服務器端的狀態(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 文檔服務器的 post 請求,并將其存儲在“payload”變量中。我們使用了“fileType”、“outputType”和“l(fā)ink”變量,我們提取的數據也是存儲在這些變量中。然而,我們還有一個“key”變量,包含當前文檔的唯一標識符。所以我們在上面添加了一個小函數來將其生成:
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)在,所有關于請求的必要的值都齊備了,我們用 jwt.sign 把它們封裝在一個令牌中:
let token = jwt.sign(payload, secret, options);
“jwt.sign”方法需要三個參數:
- Payload:包括成功轉換所需的所有參數。
- Header:包含加密算法和過期時間范圍相關信息。我們將這些參數封裝在選項變量中。
- Secret:代表 ONLYOFFICE 文檔服務器生成的密鑰。您可以在?local.json 文件中找到這個密鑰,或者通過在終端執(zhí)行如下命令:
sudo docker exec <dockerID> /var/www/onlyoffice/documentserver/npm/json -f /etc/onlyoffice/documentserver/local.json 'services.CoAuthoring.secret.session.string'
在簽署了令牌之后,我們再使用一個“axios post request”將其發(fā)送到服務器。然后我們呈現(xiàn)“converter.ejs”頁面,該頁面從 ONLYOFFICE 文檔服務器接收響應:
axios.post( 'http://127.0.0.1:83/ConvertService.ashx',{ "token": token}) .then((res) => response.render('converter.ejs', {link: res.data.fileUrl}))
這是 JSON 格式響應的樣本:
{ "endConvert": true, "fileType": "docx", "fileUrl": "https://documentserver/url-to-converted-document.pdf", "percent": 100 }
這里需要“fileUrl”元素,是指向轉換后的文件的鏈接。所以我們要獲取它,并將其發(fā)送到“converter.ejs”頁面:
.then((res) => response.render('converter.ejs', {link: res.data.fileUrl}))
});
在該頁面,我們創(chuàng)建兩個按鈕?!胺祷亍卑粹o可讓我們回到 homepage.ejs 頁面;“下載”按鈕則打開我們發(fā)送到該頁面的鏈接,并下載轉換后的文件:

請注意!如需詳細了解 JWT,請訪問我們的文檔頁面。
服務器端完整代碼如下:
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)在,我們來運行轉換器,了解如何使用!

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