console
new Vue({
el: '#app',
data() {
return {
webofficeInstance: null,
debunce: false,
config: {
"officeType": "docx",
"appId": "e13d6cf1fad141eaa08266bc5b74e141",
"fileId": "880757845375808768",
"signature": {
"sign": "0c99f78cf644d214d744f9a96a7732037b4dead5",
"nonce": "4595",
"timeStamp": "1725000218625"
},
"endpoint": "https://test-cmp-doc.woa.com",
"fileToken": "79774",
"mode": "normal",
"commonOptions": {
"isShowTitleBar": true,
"isShowToolBar": true
},
"wordOptions": {
"isShowStatusBar": true,
"isShowOutline": true
}
},
fileId: "32000",
processedKeysObject: { "F23032890003-vPXx": "腾讯音乐(北京)有限公司", "F24082920001-8CAn": "腾讯大厦", "F24082940003-fijF": "南京鸡鸣寺", "F24082970002-OmJB": "撒大大阿达是的", "F24082970004-1NWl": "招商银行", "contractTitle": "手打撒上的大萨达" }
};
},
methods: {
updateConfigFromJson() {
try {
const parsedConfig = JSON.parse(this.jsonConfig);
if (typeof parsedConfig === "object" && parsedConfig !== null) {
this.config = { ...this.config, ...parsedConfig };
this.updateWps();
} else {
alert("请输入有效的JSON格式配置");
}
} catch (error) {
console.log(error, "JDK");
}
},
async protect(){
await webofficeInstance.Application.getActiveDocument().protect('123456');
},
async unProtect(){
await webofficeInstance.Application.getActiveDocument().unProtect('123456');
},
async buildBookmarksSetText() {
if (!webofficeInstance.Application) {
console.log("Application 正在初始化");
return;
}
if (this.debunce) {
console.log("书签还在创建中");
return;
}
this.debunce = true;
const app = webofficeInstance.Application
const allBookmarks = await app.getActiveDocument().getBookmarks();
const allBookmarksLen = allBookmarks.length
for (let i = 0; i < allBookmarksLen; i++) {
const bookmarkKey = allBookmarks[i].getName().split(":")[1];
const bookmarkValue = this.processedKeysObject[bookmarkKey];
if (!bookmarkValue) {
continue;
}
const range = await allBookmarks[i].getRange();
const { start } = range.data;
const end = start + bookmarkValue.length;
const selection = await app.getActiveDocument().getSelection();
await selection.update(range);
await selection.setText(bookmarkValue);
await app.getActiveDocument().addBookmark(`书签${i + 1}:${bookmarkKey}`, {
getStart: () => start,
getEnd: () => end
});
}
const newBookmarks = await app.getActiveDocument().getBookmarks();
console.log(newBookmarks, 'newBookmarks')
while (newBookmarks.length !== allBookmarksLen) {
}
this.debunce = false;
},
titleChange(data){
this.updateBookmarkAndAddNew('contractTitle', data)
},
async updateBookmarkAndAddNew(bookmarkKey, bookmarkValue) {
if (!webofficeInstance.Application) {
console.log("Application 正在初始化");
return;
}
if (this.debunce) {
console.log("书签还在创建中");
return;
}
this.debunce = true;
const app = webofficeInstance.Application;
const allBookmarks = await app.getActiveDocument().getBookmarks();
for (let i = 0; i < allBookmarks.length; i++) {
if (allBookmarks[i].getName().split(":")[1] === bookmarkKey) {
const range = await allBookmarks[i].getRange();
const { start } = range.data;
const end = start + bookmarkValue.length;
const selection = await app.getActiveDocument().getSelection();
await selection.update(range);
await selection.setText(bookmarkValue);
await app.getActiveDocument().addBookmark(`书签${i + 1}:${bookmarkKey}`, {
getStart: () => start,
getEnd: () => end,
});
break;
}
}
this.debunce = false;
},
async updateWps() {
if (window.webofficeInstance && webofficeInstance.destroy) {
webofficeInstance.destroy();
webofficeInstance = null;
}
const iframeElement = document.getElementById("wpshtml");
let mergedConfigs = {
...this.config,
mount: iframeElement,
};
window.webofficeInstance = TencentDocsSDK.init(mergedConfigs);
await webofficeInstance.ready();
},
async getContentRange() {
const contentControls = await webofficeInstance.Application.getActiveDocument().getContentControls();
if (contentControls[0]) {
console.log('result:getId', contentControls[0].getId());
console.log('result:getRange', await contentControls[0].getRange());
console.log('result:getContent', await contentControls[0].getContent());
}
},
async getBookmarksRange() {
if (!webofficeInstance.Application) {
console.log("Application 正在初始化");
return;
}
const bookmarks = await webofficeInstance.Application.getActiveDocument().getBookmarks();
console.log(bookmarks.length)
if (bookmarks[0]) {
console.log('result:getId', bookmarks[0].getId());
console.log('result:getName', bookmarks[0].getName());
const rangeData = await bookmarks[0].getRange();
console.log('result:getRange', rangeData.data.end);
console.log('result', JSON.stringify(rangeData));
}
},
},
computed: {
jsonConfig: {
get() {
return JSON.stringify(this.config);
},
set(value) {
try {
const parsedConfig = JSON.parse(value);
this.config = { ...this.config, ...parsedConfig };
} catch (error) {
console.error("Failed to parse JSON:", error);
}
},
},
},
})
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<script src="https://unpkg.com/element-ui/lib/index.js">
</script>
<div id="app">
<div class="module-container">
1、一进入页面可以联动
2、演示下单修改标题后书签无法联动
<pre>联动对象关系: {{processedKeysObject}}</pre>
甲方:<el-input v-model="processedKeysObject['F23032890003-vPXx']"></el-input>
标题:<el-input v-model="processedKeysObject['contractTitle']" @change="titleChange"></el-input>
<div class="custom-card">
<el-form :model="config" label-width="120px" class="config-editor">
<el-form-item label="JSON配置">
<el-input
rows="2"
type="textarea"
v-model="jsonConfig"
placeholder="粘贴JSON配置"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="updateConfigFromJson">加载文档</el-button>
<el-button @click="getContentRange">内容选区</el-button>
<el-button @click="getBookmarksRange">书签选区</el-button>
<el-button @click="buildBookmarksSetText">联动书签内容</el-button>
<el-button @click="buildBookmarksSetText">联动书签内容</el-button>
<el-button @click="protect">开启文档保护 protect</el-button>
<el-button @click="unProtect">解锁文档保护 unProtect</el-button>
</el-form-item>
</el-form>
</div>
<div class="custom-card">
<div frameborder="0" id="wpshtml" class="doc-main"></div>
</div>
</div>
</div>
.inner-box {
width: 100%;
}
.container {
min-height: 800px;
height: 100%;
}
.config-editor {
padding: 10px;
box-sizing: border-box;
}
.doc-main {
height: 100vh;
min-height: 200px;
}