Vue 2.0 + C# + OnlyOffice 开发
开发环境:
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 = 0const 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; }}}