开发环境:
Windows系统、Docker运行环境、Vue2.0、.net core
安装OnlyOffice:
1. 拉取镜像:
docker pull onlyoffice/documentserver:latest
2. 启动容器:JWT_ENABLED=false 环境下需要关闭JWT校验。
docker run -d -p 9000:80 -v /path/to/data:/var/www/onlyoffice/Data -v /path/to/logs:/var/log/onlyoffice --restart=always -e JWT_ENABLED=false onlyoffice/documentserver:latest
访问:http://127.0.0.1:9000/welcome/
呈现以下界面:
3. 修改配置文件:文件允许私有ip通过,不然Docker中的镜像服务无法访问到文件服务器。
访问容器:
docker exec -it <镜像ID> bash
如:
docker exec -it 498a72efb326f8cff5449799dd2992a5f35dd92a5357d903d1fd0491e692e784 bash
安装 VIM:
apt-get update && apt-get install -y vim
- 编译default.json文件:
vim /etc/onlyoffice/documentserver/default.json
将:allowPrivateIPAddress和allowMetaIPAddress设置成True
"request-filtering-agent" : {
"allowPrivateIPAddress": true,
"allowMetaIPAddress": true
},
4. 测试网络环境:
检查容器网络:sysctl net.ipv4.ip_forward # 输出应为 net.ipv4.ip_forward = 1
测试容器镜像是否能够Ping通文件服务器。
Vue 2.0 编写代码:
1. 创建components组件:OnlyOfficeEditor.vue
<template>
<div class="onlyoffice-container">
<div v-if="loading" class="loading">编辑器加载中...</div>
<div v-if="error" class="error">编辑器加载失败: {{ error }}</div>
<div v-show="!loading && !error" :id="editorId" style="height: 800px"></div>
</div>
</template>
<script>
export default {
props: {
config: {
type: Object,
required: true,
validator: (config) => {
return ['url', 'title'].every((key) => key in config)
},
},
},
data() {
return {
editorId: `onlyoffice-${Math.random().toString(36).substr(2, 9)}`,
loading: true,
error: null,
docEditor: null,
}
},
mounted() {
this.initEditor()
},
methods: {
async initEditor() {
try {
await this.loadScript()
this.setupEditor()
} catch (err) {
this.error = err.message
} finally {
this.loading = false
}
},
loadScript() {
return new Promise((resolve, reject) => {
if (window.DocsAPI) return resolve()
const script = document.createElement('script')
script.src =
this.config.apiUrl ||
'http://127.0.0.1:9000/web-apps/apps/api/documents/api.js'
script.onload = () => {
let attempts = 0
const checkAPI = () => {
attempts++
if (window.DocsAPI) {
resolve()
} else if (attempts < 5) {
setTimeout(checkAPI, 300)
} else {
reject(new Error('OnlyOffice API加载超时'))
}
}
checkAPI()
}
script.onerror = () => reject(new Error('OnlyOffice API脚本加载失败'))
document.head.appendChild(script)
})
},
setupEditor() {
const defaultConfig = {
document: {
fileType: 'xlsx',
key: `xlsx-${Date.now()}`,
title: this.config.title,
url: this.config.url,
permissions: {
edit: this.config.editable !== false,
download: true,
print: true,
},
},
editorConfig: {
callbackUrl: this.config.callbackUrl,
lang: 'zh-CN',
user: {
id: this.config.userId || 'anonymous',
name: this.config.userName || '匿名用户',
},
customization: {
autosave: true,
forcesave: false,
},
},
}
this.docEditor = new window.DocsAPI.DocEditor(this.editorId, {
...defaultConfig,
...this.config.extraOptions,
})
},
},
beforeDestroy() {
if (this.docEditor) {
this.docEditor.destroyEditor()
}
},
}
</script>
<style scoped>
.onlyoffice-container {
position: relative;
height: 100%;
}
.loading,
.error {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.error {
color: red;
}
</style>
2. 创建主界面:text.vue
<template>
<div style="width: 100%; height: 1024px;">
<h1>运维手册</h1>
<only-office-editor style="width: 100%; height: 100%;" :config="editorConfig" @loaded="onEditorLoaded" @error="onEditorError" />
</div>
</template>
<script>
import OnlyOfficeEditor from '@/components/OnlyOfficeEditor.vue'
export default {
components: { OnlyOfficeEditor },
data() {
return {
editorConfig: {
title: '测试记录1.0.2.xlsx',
url: 'http://192.168.1.210:10177/测试记录1.0.2.xlsx',
callbackUrl: 'http://localhost:2380/SaveCallback',
userId: 'vue-user',
userName: 'Vue操作员',
editable: true,
extraOptions: {
height: '1000vh'
}
}
}
},
methods: {
onEditorLoaded() {
console.log('编辑器加载完成')
},
onEditorError(err) {
console.error('编辑器错误:', err)
}
}
}
</script>
创建后台回调接口
1. 当前回调API接口使用.net core 3.0 开发
/// <summary>
/// center for the API
/// </summary>
public class TestDemoController : ApiController
{
[HttpGet, Route("GetDocument")]
public IHttpActionResult GetDocument(string docKey)
{
var filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Documents", docKey);
return Ok(new
{
url = $"http://127.0.0.1:9000/documents/{docKey}",
fileType = Path.GetExtension(docKey).TrimStart('.')
});
}
[HttpPost, Route("SaveCallback")]
public IHttpActionResult SaveCallback([FromBody] CallbackModel model)
{
if (model.status == 2) // 2表示文档已保存
{
var savePath = Path.Combine("C:/SavedDocs", model.key);
new WebClient().DownloadFile(model.url, savePath);
}
return Json(new { error = 0 });
}
public class CallbackModel
{
public int status { get; set; }
public string key { get; set; }
public string url { get; set; }
}
}