跳到主要内容

格式合同 - 表单录入

功能说明

表单录入功能旨在提升标准合同拟制中的效率和准确性,避免手动编辑出错。

使用说明:选择已设置书签的文档,业务系统自动生成表单,用户可以在表单中录入内容。

常见需求

  1. 预设书签:打开文档进行初始化,将提前准备好的数据(来源于数据库等)分别填充到文档中对应的书签区域。
  2. 限制编辑(可选):合同进行表单录入阶段,不允许用户手动编辑文档。
  3. 填写表单
    • 点击业务系统表单中的某一项,文档自动定位到对应书签位置。
    • 在业务系统的表单中填写内容,内容自动填充到文档中对应书签区域内。
  4. 用户行为监听
    • 当用户点击进入文档中某个书签区域内,业务系统中对应表单项进入选中状态。
    • 当用户修改文档中某个书签区域的内容,修改后的书签区域内容,自动同步到业务系统对应表单项。
  5. 特殊要求(可选):
    • 文档中书签区域内容初始化阶段,API 调用不要触发文档滚动和聚焦。
    • 填写表单阶段,调用 API 定位书签、修改书签区域内容,文档不要聚焦(防止抢占表单光标,导致问题)。

代码示例

1. 预设书签

const bookmarkValues = {
"书签1": "书签1的内容",
"书签2": "书签2的内容",
"书签3": "书签3的内容",
"书签4": "书签4的内容",
"书签5": "书签5的内容"
}

const app = await ZOfficeSDK.mount(docUrl, selector, true);
await app.ready();

// 初始化时使用 bookmarkValues 中的初始值填充文档
await initializeBookmarkValues();

// 使用初始值填充书签
async function initializeBookmarkValues() {
for (const [bookmarkName, initialValue] of Object.entries(bookmarkValues)) {
try {
// 检查书签是否存在
const bookmark = await app.ActiveDocument.Bookmarks.item(bookmarkName);
if (bookmark) {
// 设置文档中书签区域的内容
await bookmark.setText(initialValue);
console.log(`已初始化书签 "${bookmarkName}" 的值为: "${initialValue}"`);
} else {
console.warn(`书签 "${bookmarkName}" 在文档中不存在`);
}
} catch (error) {
console.error(`初始化书签 "${bookmarkName}" 失败:`, error);
}
}
}

2. 限制编辑(可选)

const app = await ZOfficeSDK.mount(docUrl, selector, true);
await app.ready();

// 挂载文档后,立刻开启表单保护
await app.ActiveDocument.protect(Word.ProtectionType.FormEntry);

3. 填写表单

// 存储书签名称和输入框的映射
const bookmarkInputs = {};

// 初始化业务系统的表单
async function initBookmarkForm() {
try {
// 1. 获取文档中所有书签名称
const bookmarks = await app.ActiveDocument.Bookmarks.toJson();
console.log(bookmarks);

const formContainer = document.getElementById('bookmarkForm');
formContainer.innerHTML = '';

// 2. 根据每一个书签名,在表单区域对应添加一个输入框
bookmarks.forEach(bookmarkName => {
const formItem = document.createElement('div');
formItem.className = 'form-item';

const label = document.createElement('label');
label.textContent = bookmarkName;

const input = document.createElement('input');
input.type = 'text';
input.dataset.bookmarkName = bookmarkName;

// 3. 监听输入框获取焦点事件
input.addEventListener('focus', async (e) => {
const bookmarkName = e.target.dataset.bookmarkName;
try {
const bookmark = await app.ActiveDocument.Bookmarks.item(bookmarkName);
await bookmark.focus(); // 定位文档中对应书签
} catch (error) {
console.error('定位书签失败:', error);
}
});

// 4. 监听输入框的输入事件
input.addEventListener('input', async (e) => {
const bookmarkName = e.target.dataset.bookmarkName;
const value = e.target.value;
try {
const bookmark = await app.ActiveDocument.Bookmarks.item(bookmarkName);
await bookmark.setText(value); // 将输入框内容赋值到文档对应书签区域
} catch (error) {
console.error('设置书签内容失败:', error);
}
});

formItem.appendChild(label);
formItem.appendChild(input);
formContainer.appendChild(formItem);

// 存储书签名称和输入框的映射
bookmarkInputs[bookmarkName] = input;
});
} catch (error) {
console.error('初始化表单失败:', error);
}
}

4. 用户行为监听

// 设置事件监听器
async function setupEventListeners() {
// 监听 IDOCS.EVENT.selectionChange 事件
app.addListener('IDOCS.EVENT.selectionChange', async () => {
try {
// 清除所有表单输入框的选中状态
Object.values(bookmarkInputs).forEach(input => {
input.classList.remove('selected');
});

// 获取当前选区
const range = await app.ActiveDocument.getSelection();
if (!range) return;

// 获取当前选区中的书签
const bookmark = await range.Bookmarks.item(1);
if (!bookmark) {
// 比较当前选区和每一个书签的区域关系
for (const [bookmarkName, input] of Object.entries(bookmarkInputs)) {
try {
const bookmark = await app.ActiveDocument.Bookmarks.item(bookmarkName);
const bookmarkRange = await bookmark.range;
const relation = await range.compare(bookmarkRange);
// 检查选区是否与书签区域重叠
if (relation === Word.LocationRelation.equal || relation === Word.LocationRelation.inside) {
input.classList.add('selected');
break;
}
} catch (error) {
console.error('检查书签区域失败:', error);
}
}
}
} catch (error) {
console.error('处理选区变化事件失败:', error);
}
});

// 监听 IDocs.Event.ContentChange 事件
app.addListener('IDocs.Event.ContentChange', async (content) => {
try {
if (content.type === 'bookmark' && content.data) {
content.data.forEach(change => {
const { id, newData } = change;
const input = bookmarkInputs[id];
if (input) {
// 将书签区域的最新内容,赋值给表单中对应输入框
input.value = newData || '';
}
});
}
} catch (error) {
console.error('处理内容变化事件失败:', error);
}
});
}

5. 特殊要求(可选)

const app = await ZOfficeSDK.mount(docUrl, selector, true);
await app.ready();

// 等待应用加载完成后初始化表单
// 初始化阶段,API 调用不允许聚焦文档,不允许滚动视图
await app.setUIState({ cursorContext: { focus: false, scroll: false }});
await initBookmarkForm();

// 初始化结束后,后续 API 调用允许滚动视图,不允许聚焦文档
await app.setUIState({ cursorContext: { focus: false, scroll: true }});
await setupEventListeners();