这次我们领导突然给我安排这一个业务,开始也是把我震惊到了。我们公司找了两个外包负责的业务,B公司负责管理一些加盟商信息,然后审批过了之后就把数据发送到C公司生成在线合同,然后发送给客户签署。这些业务完全都已经跑通了的,只是随时会出现字段,或者数据填充错误,现在我们领导就想确认前先生成一个预览合同。让法务部门先确认一下字段是否填写正确。
方案探索
html
: 最开始我想着,前端搞Word可能很麻烦,干脆直接把Word保存为html,直接渲染网页确认,可是保存之后样式丢失太严重了,完全没法看。
ActiveXObject
: 这是一个IE浏览器特有的对象,兼容性不咋行而且操作很繁琐,需要一个步骤搞,麻烦
docx
: 一个是使用js生成Word文件的库,必须使用他内置方法来组合内容, 很是麻烦
docxtemplater
: 一个渲染已有Word文件,通过变量替换来生成新Word文件
很明显目前最后一个方案非常适合我现在使用的场景
浏览器拓展
1 | { |
Word模版我想放在插件包里面动态更新, 如果通过对象存储和其他方式分发比较麻烦,最开始我以为他插件包也是一个动态网站,可以直接通过fetch('/')
访问包里面的静态文件。
可是在content.js
文件里面访问的是业务网站的内容,然后background.js
里面直接报错了。
最后我关注到了插件有一个web_accessible_resources
参数,可以把插件包里面的内容提供给页面使用。
然后百度到通过chrome.runtime.getURL
方法就可以访问到插件包设置出来的资源了
1 | "web_accessible_resources": [ |
大体思路是有有了但是具体如何实现呢。
我这里采用了监听DOM
的变化,然后再业务网站上添加一个按钮,来触发插件提供的功能。
DOM
监听, 我这里数据表单默认没有展示,在Drawer
中展示的1
2
3
4
5
6
7
8
9
10new MutationObserver(function () {
Debounce(function () {
if (
document.body.className == 'el-popup-parent--hidden' && // 判断蒙版展开
document.querySelector('.head-title')?.innerText?.includes('') //并且表单头包含特定条件
)
// 满足条件插入按钮
insertButton();
});
}).observe(document.body, { childList: true, subtree: true });
数据爬取
数据如何爬取呢, 还有字段取名,这个是真的太难为人了取名。后来我一想又不是什么大项目,就给一个内部员工使用,没必要那么麻烦;
我直接找到所有的表单项目,把表单label
做键名,输入内容就直接查找表单项目里面的input
或者其他表单内容的value
值就行,我预览也不需要展示枚举类型;
1 | const inputObj = target.getElementsByClassName('form-item-view'), |
- 格式化单个项目
1 | /** |
- 数据整理
1
2
3
4for(let item of inputObj) {
const [name, ...list] = getFormItem(item);
formMap.set(name, list.reverse()[0]);
}
这样跑一遍基本就爬取到所有表单数据了。
文档渲染
Word
模版文档就需要用到docxtemplater
和pizzip
这两个js库了。 直接复制官网Dome
下来跑一遍就行了,我这没用用它加载文档的工具函数。
1 | ArrayBufferimport PizZip from "pizzip"; |
PizZip
这个方法必须传入ArrayBuffer
才行,我最开始以为blob
就可以。排查了很久
1 | const file = await getFile(chrome.runtime.getURL(`static/${fileName}.docx`)); |
到这里我们就已经得到生成的blob
对象,如果要下载的话使用URL.createObjectURL(blob)
方法,链接到a
标签上就行。如果需要下载多个文件最好用iframe