前段时间,客户提了个需求,想把订单合同做成线上签名并在线生成合同,生成的合同还要打印出来,还要我两天做完,WTF,接到需求的那一刻我是懵逼的,我只是个瑟瑟发抖的小前端啊,话说这也需要研究一下怎么做的吧。
瑟瑟发抖之余,我就在考虑具体实现的步骤,简单划分了下 --->
- 用canvas实现手写签名
- 将签名展示在合同上
- 提交合同的同时生成pdf(合同内容+签名)
- 将生成的合同保存到服务端
看完是不是觉得很简单,不用两天,给我三五个小时就搞定了。事实证明我还是太年轻了,我google了几个案例后,发现最佳实现方案是用signature_pad实现签名,然后用(html2canvas+jsPdf)生成pdf文档。
于是我便开始动手写demo,签名没啥问题,我之前自己也写过canvas实现写字,但是懒得再去重构项目和做模块化扩展。html2canvas也没问题,用网页生成的图片文件很清晰,还原度很高,至于生成pdf嘛,效果就一般了。
主要问题是如下:
- 生成的pdf及其不清晰,
- 分页打印的位置裁切也存在问题
- 手机端展示的合同的dom结构布局和打印的A4纸上的布局有很大不同
我也尝试过多种方案,依旧没能解决,期间想过用一个隐藏dom来写一套A4纸的样式用于打印,后来发现清晰度和裁剪问题不好解决,于是便换了种思路,想通过服务端来解决。
在github上逛了逛,发现了pdfmake这个神器,立马看了文档,开始写demo,实践了一遍后发现,这个比较靠谱,生成的文档也很清晰。
具体能实现的如下:
- 自定义样式(字体,颜色,下划线,对齐方式,边距)
- 插入图片
- 定位(相对定位,绝对定位)
- 水印,页眉页脚
这些就够了,可是还存在一些问题(不知道是不是打开的方式不对)
- 对中文的支持很差,目前只能用微软雅黑
- 原始文档需要自己手动去设置,当然也可以使用js去生成
最终我还是用这个插件实现了想要的效果。
项目上线后,我自己撸了个demo,放在github上,有兴趣的可以下载下来看一看
//项目结构
├── README.md
├── app
│ ├── fonts
│ │ └── msyh.ttf //字体文件
│ ├── images
│ │ ├── qrcode.png //用到的图片
│ │ └── snh.jpg
│ ├── middleware
│ │ └── generatePdf.middleware.js //生成文档js
│ ├── models
│ │ └── doc.model.js //文档原型
│ └── routers
│ └── index.js //路由文件
├── app.js
├── package.json
└── tempFiles //缓存目录
效果截图(截图效果太渣,文档很清晰,打印完全没问题)
有需要的可以自取
git clone https://github.com/zangse/GeneratePDF
npm install
npm run start
在浏览器打开
http://localhost:3000/pdf
这个pdfmake也可以在浏览器端实现,鉴于需要加载的字体太大(微软雅黑.ttf ---> 10M+),我放弃了这个操作。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。