赞
踩
文档转换是非常常用、非常有价值的功能,可以帮助我们处理多种文档类型。ONLYOFFICE 编辑器可以轻松地将文档转换为多种格式。在这篇博文中,我们会向您展示,如何构建在 ONLYOFFICE 转换 API 上运行的在线转换器。
使用文档转换服务,您可就各种类型的 Office 文档做转换:文本、表格、幻灯片、表单、PDF 和电子书。它帮助您基于文档和表格创建 PDF,将教科书转换为电子书,将演示文稿转换为图片文件,等等。ONLYOFFICE 支持 50 多种文件类型。
我们的转换 API 通过“文档转换服务”运行。它是 ONLYOFFICE 文档服务器的一部分,支持我们将各种文档文件转换为合适的格式。
转换要分几个步骤进行:
“文档管理器”和“文档存储服务”是客户端和服务器端的工具,方便选择和存储文档供进一步转换。不过,我们的 web 应用会处理这些任务,这得益于我们正在构建的自定义转换器。
我们的转换器基于 NodeJS。因此,对于这个项目,我们需要如下条件:
我们会使用 Axios 包向 ONLYOFFICE 文档服务器发送一个 post 请求,并使用 Jsonwebtoken 包签署一个 JWT 令牌。从版本 7.2 开始,JWT 认证默认处于启用状态。
或者,您还可以通过另一个选项,在 JWT 认证停用的情况下运行 ONLYOFFICE 文档服务器镜像。为此,请在终端执行如下命令:
sudo docker run -i -t -d -p 80:80 -e JWT_ENABLED=false onlyoffice/documentserver
我们的转换器向 ONLYOFFICE 文档服务器发送的“post 请求”如下:
- {
- "async": true,
- "filetype": fileType,
- "key": key,
- "outputtype": outputType,
- "title": `Converted Document.${outputType}`,
- "url": link
- }
“fileType”、“outputType”和“url”参数的值是从我们应用的客户端获取,存储在变量中。“key”参数的值也是随机生成,存储在变量中。
将所需的包安装好后,我们前往“app.js”文件,将它们与“bodyParser”一起初始化,以处理“post 请求”数据。我们还创建了一个公开文件夹和一个视图引擎:
- 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){
- }
-
现在我们花点时间,看看转换器的客户端。就是在这里,我们要输入所有所需数据:
客户端包括两个 EJS 页面:
我们来详细看看“homepage.ejs”。这里我们创建了一个表单,将数据发送到“post”路由。首先,我们获得一个原始文件的URL。我们将把其存储在服务器端的“link”变量中:
- <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>
我们用一个按钮将所有数据发送到“转换器”post 路由:
- <div class="button">
- <button type="submit" id="download" disabled="true" class="btn btn-lg btn-primary btn-block">Convert</button>
- </div>
- </form>
提取的数据会在我们应用的服务器端进行解析。现在,我们前往“app.js”文件去获取:
- app.post ('/converter', function(req, response){
- let link = req.body.link;
- let outputType = req.body.outputType;
- let fileType = req.body.inputType;
-
- });
现在我们看看第二个组合框,它将“outputType”值发送到“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 代码,并将动态列表并入我们的用户界面。
“文档转换服务”是一个非常强大的工具,能够转换各种类型的文件。所以我们的目标是利用一个动态列表,让我们为转换后的文件选择一种格式。这个列表会显示针对特定类型的原始文件的所有可用选项。
为此,我们创建一个 JSON 文件,按照每个特定的类型来存储数值:
请注意!在示范中,我们只列出了最常用的 OOXML 格式。如要了解所有受支持的转换选项,请访问我们的文档页面。
然后我们添加一个函数来生成这个动态列表:
- 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”变量,以便在后面使用这个值。然后我们发出一个 AJAX 请求来加载 JSON 数据。之后,我们使用“type”变量的值作为索引,迭代加载的数据,将其值插入下拉列表的选项中。
现在,我们每次选择原始文件的类型时,脚本就会执行,并按照原始文件格式向我们显示可用的转换选项。
而在我们得到所有需要的数据后,点击“转换”按钮即可将其发送到转换器路由。
但实际不是这样。为了让我们的应用更具互动性,我们会添加函数,以正确的顺序激活组合框和按钮元素:
- 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();
- };
- }

我们来看看服务器端的状态:
- 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”和“link”变量,我们提取的数据也是存储在这些变量中。然而,我们还有一个“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;
- };
现在,所有关于请求的必要的值都齐备了,我们用 jwt.sign 把它们封装在一个令牌中:
let token = jwt.sign(payload, secret, options);
“jwt.sign”方法需要三个参数:
sudo docker exec <dockerID> /var/www/onlyoffice/documentserver/npm/json -f /etc/onlyoffice/documentserver/local.json 'services.CoAuthoring.secret.session.string'
在签署了令牌之后,我们再使用一个“axios post request”将其发送到服务器。然后我们呈现“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”元素,是指向转换后的文件的链接。所以我们要获取它,并将其发送到“converter.ejs”页面:
- .then((res) => response.render('converter.ejs', {
- link: res.data.fileUrl
- }))
- });
在该页面,我们创建两个按钮。“返回”按钮可让我们回到 homepage.ejs 页面;“下载”按钮则打开我们发送到该页面的链接,并下载转换后的文件:
请注意!如需详细了解 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'));

现在,我们来运行转换器,了解如何使用!
ONLYOFFICE 解决方案的功能非常丰富。这些解决方案为用户和开发者提供独特体验,让他们能够以多种方式操作 ooXML 文档。我们希望您觉得如上提到的信息很有用,并将其应用在您未来的项目中。欢迎您发表评论、提出问题或与我们分享您的想法,我们乐意接受建议、展开合作。祝您的探索一切顺利!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。