Online editing of WebOffice documents

Introduction

  The WebOffice control described in this article is a product developed by Guangzhou Huaertai Technology Co., Ltd. to process Office files in web pages. The WebOffice control supports almost all requirements for online document functions, such as online creation , editing , saving , multi-person collaboration Office files, etc.
It has the following core functions

  1. Remote opening and saving : WebOffice is fully automatic, no need to manually upload and download, complies with the standard HTTP/HTTPS transmission protocol, and supports server synchronous and asynchronous ways to save files.
  2. Intelligent filling/reading : data can be extracted from specified fields in the database, filled in the specified position of the document, and data can also be read from the specified position of the document to the specified field of the database.
  3. Powerful API interface and VBA expansion capability : Efficient API and VBA expansion, any office document expansion function can be integrated with JS by VBA to meet business needs.

  Official website entrance

Advantages and disadvantages

  Compared with the WebOffice provided by WPS, the WebOffice control of Guangzhou Huaertai Technology Co., Ltd. has the advantages of low price, simple access (no additional installation package is required for the front end) and rich domes.

  The WebOffice control also has a fatal shortcoming, that is, the client needs to install the WebOffice control locally . In addition, the operation window of the WebOffice control pops up a separate window, and the console cannot be opened in this window, which is inconvenient for debugging, and the style is also very old.

  There seems to be no documentation for the WebOffice control (I didn’t find it, which is the reason for writing this article). Although a large number of demos are provided to implement various functions, they do not cover all operations, so sometimes you have to go to Microsoft Office. document.

Several document addresses that may be useful

memo

WORD
	WebOffice.ActiveDocument.Tables(1); // 返回文件的第一个表格对象
    WebOffice.ActiveDocument.Tables.Count; // 返回文档中表格的数量
    WebOffice.ActiveDocument.Tables(1).Rows.Count; // 返回文档中第一个表格的行数
    WebOffice.ActiveDocument.Tables(1).Columns.Count; // 返回文档中第一个表格的列数
    WebOffice.ActiveDocument.Tables(1).Rows(1).Delete(); // 删除表格的第一行
    WebOffice.ActiveDocument.Application.Selection.Type // number 1 表示没有选中内容。 2 表示选中文本内容
    console.log(WebOffice.IsDirty); // 只读属性,表示文档是否有修改
    // 保护文档,使文档那个不可编辑
    WebOffice.ActiveDocument.Protect(3,false,this.pwd,false,true);
    // 先解除保护,使文档可编辑
    WebOffice.ActiveDocument.Application.ActiveDocument.UnProtect(this.pwd);

dome

Document Operations Page
<template>
<div class="web-edit">
    <div class="left">
        <div class="btn-area">
            <el-button size="small" @click="quiteAction">退出</el-button>
            <el-button size="small" type="primary" @click="HttpPostSave">保存</el-button>
        </div>
        <div class="content-warp">
            <template v-for="classifyLevel1 in fieldList" >
                <p class="title max-title" :key="classifyLevel1.type">
                    <span @click="unfoldAction(classifyLevel1)" class="can-click">
                        {
   
   {classifyLevel1.type}}
                        <i v-if="classifyLevel1.isUnfold" class="el-icon-caret-bottom"></i>
                        <i v-else class="el-icon-caret-right"></i>
                    </span>
                </p>
                <template v-if="classifyLevel1.isUnfold">
                    <div class="field-box" v-for="classifyLevel2 in classifyLevel1.fieldList" :key="classifyLevel2.classifyName">
                        <p class="title">
                            <span @click="unfoldAction(classifyLevel2)" class="can-click">
                                {
   
   {classifyLevel2.classifyName}}
                                <i v-if="classifyLevel2.isUnfold" class="el-icon-caret-bottom"></i>
                                <i v-else class="el-icon-caret-right"></i>
                            </span>
                        </p>
                        <div class="field-list" v-if="classifyLevel2.isUnfold">
                            <span @click="insertAction(item, classifyLevel1.type)" class="item can-click" :class="{
     
     'is-checked': item.checked}" v-for="item in classifyLevel2.fieldList" :key="item.id">{
   
   {item.name}}</span>
                        </div>
                    </div>
                </template>
            </template>
            
        </div>
    </div>
    <div class="right">
        <object classid="clsid:FF09E4FA-BFAA-486E-ACB4-86EB0AE875D5" codebase="http://www.officectrl.com/weboffice/WebOffice.ocx#Version=2018,1,6,2" id="WebOffice" width="100%" height="100%" ></object>
    </div>
 </div>
</template>
<script>
import {
      
       temDetail, getFieldList, saveFieldsList } from "@/api/baseInfo";
import {
      
       setToken } from '@/utils/auth'

export default {
      
      
    data () {
      
      
        return {
      
      
            strUrl: '',
            doctype: '',
            imgList: [],
            WebOffice: '',
            fileName: '',
            orderId: null,
            editId: null,
            pwd: Date.now().toString(),
            fieldList: [],
            fields: [], // 已选的字段列表
        }
    },
    created() {
      
      
        let query = this.$route.query;
        let token = query.token;
        setToken(token, false);
        if (query.id) {
      
      
            this.editId = query.id;
            this.getFieldList();
            this.temDetail();
        }
    },
    mounted() {
      
      
        
    },
    methods:{
      
      
        // 插入表格
        /**
         * data 表格的数据;
         * columnsCount 列数;
         * rowsCount 行数;
         * isAdapt 是否自动调整表格中单元格的大小以适应单元格的内容(word 中)(可选)
         */
        insertTable(data, columnsCount, rowsCount=1, isAdapt=true) {
      
      
            const range = WebOffice.ActiveDocument.Application.Selection.Range;
            const table = WebOffice.ActiveDocument.Tables.Add(range, rowsCount, columnsCount, isAdapt);
            if (table.Rows.Count > rowsCount) {
      
      
                table.Rows(table.Rows.Count).Delete();
                alert("提示:两个表格之间至少有一行空行");
                return;
            }
            data = Array.isArray(data) ? data : [];
            if (rowsCount < 1) {
      
      
                alert("表格的行数不能小于 1");
            } else {
      
      
                data.forEach((rows, rowIndex) => {
      
      
                    if (Array.isArray(rows)) {
      
      
                        // 二维数组,不止一行的情况下
                        rows.forEach((cell, columnIndex) => {
      
      
                            table.Cell(rowIndex + 1, columnIndex + 1).Range.InsertAfter(cell);
                        })
                    } else {
      
      
                        // 只有一行
                        table.Cell(1, rowIndex + 1).Range.InsertAfter(rows);
                    }
                })
            }
            range = null;
            table = null;
            // WebOffice.ActiveDocument.Tables(1); // 返回文件的第一个表格对象
            // WebOffice.ActiveDocument.Tables.Count; // 返回文档中表格的数量
            // WebOffice.ActiveDocument.Tables(1).Rows.Count; // 返回文档中第一个表格的行数
            // WebOffice.ActiveDocument.Tables(1).Columns.Count; // 返回文档中第一个表格的列数
            // WebOffice.ActiveDocument.Tables(1).Rows(1).Delete(); // 删除表格的第一行
            // WebOffice.ActiveDocument.Application.Selection.Type // number 1 表示没有选中内容。 2 表示选中文本内容
            // console.log(WebOffice.IsDirty); // 只读属性,表示文档是否有修改
            // 保护文档,使文档那个不可编辑
            // WebOffice.ActiveDocument.Protect(3,false,this.pwd,false,true);
            // 先解除保护,使文档可编辑
            // WebOffice.ActiveDocument.Application.ActiveDocument.UnProtect(this.pwd);
        },
        unfoldAction(item) {
      
      
            item.isUnfold = !item.isUnfold;
        },
        insertAction(field, type) {
      
      
            let isRevise = WebOffice.ActiveDocument.Application.Selection.Type === 2;
            // 先解除保护,使文档可编辑
            // WebOffice.ActiveDocument.Application.ActiveDocument.UnProtect(this.pwd);
            if (isRevise) {
      
      
                WebOffice.ActiveDocument.Application.Selection.Cut(); // 删除所选内容,并将内容移至剪切板
            }
            if (type === "表格") {
      
      
                let columnsCount = field.header.length, rowsCount = 2;
                let data = [field.header, field.header.map(() => "")];
                this.insertTable(data, columnsCount, rowsCount);
            } else {
      
      
                // 在光标处插入文本
                WebOffice.ActiveDocument.Application.Selection.Range.InsertAfter(field.code);
            }
            if (!this.fields.includes(field.id)) {
      
      
                this.fields.push(field.id);
            }
            // 保护文档,使文档不可编辑
            // WebOffice.ActiveDocument.Protect(3,false,this.pwd,false,true);
        },
        temDetail() {
      
      
            temDetail(this.editId)
            .then(res => {
      
      
                let strUrl = res.alioss.attachmentUrl;
                let fileName = res.alioss.fileName;
                this.fileName = fileName;
                let doctype = '';
                let index = fileName.lastIndexOf('.');
                doctype = fileName.substring( index + 1, fileName.length);
                const WebOffice = document.getElementById('WebOffice');
                // 正确设置 UserName 和 Authorizer 才能正确打开
                WebOffice.UserName="公司名称";
                WebOffice.Authorizer="www.officectrl.com";
                this.$nextTick(() => {
      
      
                    setTimeout(() => {
      
      
                        WebOffice.MenuBar = false;
                        WebOffice.Toolbars = true; // 是否显示工具栏
                        WebOffice.Titlebar = false;
                        WebOffice.Open(strUrl, true, doctype);
                        // WebOffice.ActiveDocument.Protect(3,false,this.pwd,false,true);
                    }, 1000)
                })
            })
            .catch(error => {
      
      
                console.log(error);
            })
        },
        quiteAction() {
      
      
            window.close();
        },
       	// 保存文件(同步保存)
        HttpPostSave() {
      
      
            this.saveFieldsList();
            const strSaveUrl = process.env.VUE_APP_BASE_API + '/api/retemplate/upload';
            try {
      
       
                WebOffice.HttpInit();
                WebOffice.HttpAddPostString('id', this.editId);
                WebOffice.HttpAddPostCurrFile("docfile","");//此句为固定语句,不管是保存word还是excel,ppt等都这样写
                const strResults = WebOffice.HttpPost(strSaveUrl);
                // console.log(strResults);
                // strResults;//如果保存成功,编程时让服务器接收代码如upload.jsp,upload.aspx,upload.php等返回空值或OK字串。
                // if(strResults.indexOf('ok') > 1)
                alert('office文档保存成功!');
            }
            catch(e) {
      
      
                alert('发生错误!请使用查阅返回值!');
            }	
        },
        // 获取可配置的字段
        getFieldList() {
      
      
            getFieldList(this.editId)
            .then(res =>{
      
      
                this.fieldList = res.map(item => {
      
      
                    this.$set(item, "isUnfold", true);
                    if(item.fieldList && item.fieldList.length) {
      
      
                        item.fieldList.forEach(el => {
      
      
                            this.$set(el, "isUnfold", true);
                        })
                    }
                    return item;
                });
            })
            .catch(err => {
      
      
                console.log(err);
            })
        },
        saveFieldsList() {
      
      
            let params = {
      
      
                id: this.editId,
                fields: this.fields
            }
            saveFieldsList(params)
            .then(res => {
      
      
                alert('保存成功');
            })
            .catch(err => {
      
      
                console.log(err);
            })
        },
    }
} 
</script> 
<style lang="scss" scoped>
.web-edit {
      
      
    display: flex;
    width: 100%;
    height: 100%;
    box-sizing: border-box;
    overflow: hidden;
    background-color: #fff;
    .can-click {
      
      
        cursor: pointer;
    }
    .left {
      
      
        display: flex;
        flex-direction: column;
        font-size: 14px;
        width: 400px;
        padding-left: 10px;
        .btn-area {
      
      
            padding: 30px 0 20px;
            text-align: center;
            .el-button {
      
      
                width: 100px;
                & + .el-button {
      
      
                    margin-left: 20px;
                }
            }
        }
        .content-warp {
      
      
            flex: 1;
            overflow-x: hidden;
            overflow-y: auto;
        }
        .title {
      
      
            .el-icon-caret-right, .el-icon-caret-bottom {
      
      
                color: #409eff;
            }
        }
        .max-title {
      
      
            margin-top: 10px;
            font-size: 16px;
        }
        .field-box {
      
      
            padding: 10px 15px 0;
            .field-list {
      
      
                padding: 10px 10px 0;
                .item {
      
      
                    display: inline-block;
                    padding: 0 8px;
                    margin: 5px 15px 5px 0;
                    font-size: 14px;
                    line-height: 23px;
                    background-color: #eee;
                    white-space: nowrap;
                    border-radius: 3px;
                    &:hover, .is-checked{
      
      
                        color: #fff;
                        background-color: #409eff;
                    }
                }
            }
        }
    }
    .right {
      
      
        flex: 1;
        height: 100%;
        #WebOffice {
      
      
            width: 100%!important;
            height: 100%!important;
        }
    }
    
}
</style>
How to open the edit page
// 编制动作
      editAction(id) {
    
    
        let pre = "weboffice://|Officectrl|"; // 这个很关键!!!
        let host = window.location.host;
        let browerType = this.getBrowser();
        let token = getToken();
        if (browerType == 0) {
    
    
          const {
    
     href } = this.$router.resolve({
    
    
            name: "edit",
            query: {
    
     'id': id, 'token': token}
          });
          window.open(href, '_blank');
        } else {
    
    
          let strUrl = pre + 'http://' + host + '/#/edit?id=' + id + '&token=' + token;
          window.open(strUrl, '_blank');
        }
      },
      // 检查浏览器类型
      getBrowser() {
    
    	
        let Sys = {
    
    };
        let ua = navigator.userAgent.toLowerCase();
        let s;
        let ver;
        (s = ua.match(/edge\/([\d.]+)/)) ? Sys.edge = s[1] :
        (s = ua.match(/rv:([\d.]+)\) like gecko/)) ? Sys.ie = s[1] :
        (s = ua.match(/msie ([\d.]+)/)) ? Sys.ie = s[1] :
        (s = ua.match(/firefox\/([\d.]+)/)) ? Sys.firefox = s[1] :
        (s = ua.match(/chrome\/([\d.]+)/)) ? Sys.chrome = s[1] :
        (s = ua.match(/opera.([\d.]+)/)) ? Sys.opera = s[1] :
        (s = ua.match(/version\/([\d.]+).*safari/)) ? Sys.safari = s[1] : 0;
        if (Sys.edge) return 1;
        if (Sys.ie) return 0;
        if (Sys.firefox) return 1;
        if (Sys.chrome){
    
     ver = Sys.chrome;ver.toLowerCase();var arr = ver.split('.');if(parseInt(arr[0])>43){
    
    return 1;}else{
    
    return 0;}}
        if (Sys.opera) return 1;
        if (Sys.safari) return 1;
        return 1;
      },
Effect

Please add a picture description

Guess you like

Origin blog.csdn.net/dark_cy/article/details/121008400