表格技术七十二变丨手把手教你用Canvas电子表格做电子签名
myzbx 2025-05-05 17:36 60 浏览
日常生活工作学习中,大家对电子表格必定不陌生。从工作数据汇总分析到出门收据各种电子发票,这些都是由电子表格制作出来的。
不过大家对电子表格的印象可能停留在这里:
标准行列数据统计的表格样式。但其实,表格也可以是这样的:
工作中遇到需要实现的表格情况往往比大家想象的要更加复杂,最近我们在做客户支持的工作过程中遇到了一个客户,他需要借助电子表格表格实现合同中的电子签名。
电子签名通俗来说就是通过技术手段实现在电子文档上加载电子形式的签名,其作用类似于纸质合同上的手写签名或加盖的公章。在企业工作流审批、请柬、单据保全等场景应用广泛。
在经济活跃跨区域化现象越来越多的今天,作为电子表格的一个重要使用场景,电子合同可以实现异地签约,签署的时间第点更加自由;面对大批量的合同签署也可以轻松解决;同时传统纸质合同的管理更加方便,避免了纸质合同因保存管理问题而出现损坏。
而今天,客户在实际项目中需要实现的内容长这样:
看到这里,有些小伙伴可能会说这有什么难的,虽然这个东西长相酷似word,
但不就是电子表格去掉边框线吗?
如果只是简单的表格框内容,下段代码就可以简单的实现表格的绘制。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>02Canvas案例-绘制表格</title>
</head>
<body>
<div id="container">
<canvas id="cavsElem">
</canvas>
</div>
<script>
(function(){
var canvas=document.querySelector('#cavsElem');
var ctx=canvas.getContext('2d');
canvas.width=600;
canvas.height=600;
canvas.style.border='1px solid green';
var rectH=10;
var rectW=20;
ctx.lineWidth=.5;
//绘制表格
// 第一步: 绘制横线
for(var i=0;i<canvas.width;i++){
ctx.moveTo(rectW*i,0);
//如果不设置moveTo,当前画笔没有位置
ctx.lineTo(rectW*i,canvas.height);
}
//第二步:绘制竖线:如果绘制的格子的宽高相等,可以将for循环放到一个里面;
for(var i=0;i<canvas.height;i++){
ctx.moveTo(0,rectH*i);
ctx.lineTo(canvas.width,rectH*i);
}
ctx.stroke();
}())
</script>
</body>
</html>但是放大仔细看看,就会发现情况并不如我们所想的这么简单。
在这个合同中,我们除了要隐藏边框线,还要考虑边缘留白、图片跨越、页面滚动后截图不全等问题。 而借助电子表格在数据处理和分析方面天生具备的优势,可以很容易的实现电子签名功能。
我们今天就一起来尝试通过基于Canvas的电子表格来实现电子签名并导出PDF的项目开发需求。
环境准备
- 环境准备:安装SpreadJS 前端表格插件,并通过插件绘制canvas画布。
2. 初始化Spread工作簿,并导入合同模板
3. 创建Canvas画布并引用esign.js画法实现手写签名区域
4. 通过自定义超链接跳转命令,签名区域呼出
5. 将签名区域转化为图片设置为背景图片
6. 使用SpreadJS提供的导出PDF接口将签署的文件导出
电子签名的实现
初始化Spread工作簿
1、引入以下文件
<link rel="stylesheet" type="text/css" href="node_modules/@grapecity/spread-sheets/styles/gc.spread.sheets.excel2013white.css">
<script src="node_modules/@grapecity/spread-sheets/dist/gc.spread.sheets.all.min.js" type="text/javascript"></script>
<script src="new2.ssjson" type="text/javascript"></script>2、创建用于承载SpreadJS的DOM
<div id="ss" class="sample-spreadsheets" style="height: 900px;">3、用JS获取DOM对象并进行初始化
var spread = new GC.Spread.Sheets.Workbook(document.getElementById("ss"));4、导入合同模板
spread.fromJSON(str);到这里,我们Spread工作簿已经初始化完成了。当然,你也可以添加对应的CSS调整表单的大小。
关于模板的制作,你可以在在线表格编辑器中根据需求进行绘制,并导出为ssjson文件并通过fromJSON导入到我们的表单中。
接下来,用Canvas画布来实现手写签名区域。
手写签名区域
1、首先,我们先创建签名区域的DOM元素,并定义一个Canvas画布,默认情况下不显示。
<div class="containter" id="box" style="display: none;">
<div class="canvasDiv">
<div id="editing_area">
<canvas id="canvasEdit"></canvas>
</div>
</div>
<div class="btnDiv">
<a id="sign_clear" class="clearBtn">清空</a>
<a id="sign_clear2" class="clearBtn">签署</a>
</div>
</div>2、引用esign.js和jQuery。Esign.js是一种用鼠标在canvas上绘制的画法。
<script type="text/javascript" src="js/esign.js"></script>
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>3、初始化
$(document).esign("canvasEdit", "sign_show", "sign_clear", "sign_ok");
$(document).on('click', '#sign_clear2', takeScreenshot);Canvas画布中利用自定义单元格,理论上也是能开发出能够直接签名的单元格。
用户可以直接在单元格进行签名,有兴趣的小伙伴可以尝试用自定义单元格实现。
自定义超链接命令
1、创建超链接
sheet.setValue(32, 10, "审核人签名:")
sheet.setHyperlink(32, 10, { command: "popup" });2、为超链接设置命令,点击弹出画布
spread.commandManager().register("popup",{
canUndo: true,
execute: function (context, options, isUndo) {
var Commands = GC.Spread.Sheets.Commands;
// 在此加cmd
options.cmd = "popup";
if (isUndo) {
Commands.undoTransaction(context, options);
return true;
} else {
Commands.startTransaction(context, options);
document.getElementById("box").style.display = "block";
Commands.endTransaction(context, options);
return true;
}
}
});指定DOM转为图片并设置为单元格背景
1、利用canvas的接口,将画布转为base64,调用接口设置背景
function convertCanvasToImage(canvas) {
return canvas.toDataURL("image/png");
};
function takeScreenshot() {
var canvas = document.getElementById("canvasEdit");
var imgUrl = convertCanvasToImage(canvas); //截取图片路径,该路径为服务器参数
var sheet = spread.getSheet(0);
sheet.getCell(32,13).backgroundImage(imgUrl);
sheet.getCell(35,13).backgroundImage(imgUrl);
sheet.getCell(38,13).backgroundImage(imgUrl);
}2、关闭签名画布
function tishi(){
document.getElementById("box").style.display = "none";
}
setTimeout(tishi,100)将电子签名导出PDF
上面已经实现了电子签名内容,但是我们都知道合同需要有打印输出功能,接下来我们继续介绍如何使用pdf打印输出电子签名。
1、引用PDF拓展文件以及filesaver
<script src="node_modules/@grapecity/spread-sheets-pdf/dist/gc.spread.sheets.pdf.min.js" type="text/javascript"></script>
<script src="node_modules/file-saver/dist/FileSaver.min.js" type="text/javascript"></script>2、调用接口导出PDF
spread.savePDF(function (blob) {
var fileName = 'download';
saveAs(blob, fileName + '.pdf');
}, function (error) {
console.log(error);
}, {
title: 'Test Title',
});注意:导出中文字符需要注册对应的字体。
总结
以上,我们实现了基于Canvas电子表格实现电子签名并使用PDF导出打印的完整功能,由于Canvas完全取代了页面的dom结构,因此打印时不需要遍历要打印的dom节点的子节点,也不必将每一页所能打印的dom节点高度累加,这样做可以不用再计算dom节点的高度,大幅节省了系统性能,同时实现了较细的页面颗粒度,不会造成大块空白的情况,完全模拟出了word生成pdf的那种效果。同时,也解决了我们在文章开头中提到缘留白、图片跨越、页面滚动后截图不全三个问题。
关注我们的账号,接下来还会为大家带来更多在工作项目中遇到的有趣内容。
来都来了,点个赞再走吧吧~
相关推荐
- 如何设计一个优秀的电子商务产品详情页
-
加入人人都是产品经理【起点学院】产品经理实战训练营,BAT产品总监手把手带你学产品电子商务网站的产品详情页面无疑是设计师和开发人员关注的最重要的网页之一。产品详情页面是客户作出“加入购物车”决定的页面...
- 怎么在JS中使用Ajax进行异步请求?
-
大家好,今天我来分享一项JavaScript的实战技巧,即如何在JS中使用Ajax进行异步请求,让你的网页速度瞬间提升。Ajax是一种在不刷新整个网页的情况下与服务器进行数据交互的技术,可以实现异步加...
- 中小企业如何组建,管理团队_中小企业应当如何开展组织结构设计变革
-
前言写了太多关于产品的东西觉得应该换换口味.从码农到架构师,从前端到平面再到UI、UE,最后走向了产品这条不归路,其实以前一直再给你们讲.产品经理跟项目经理区别没有特别大,两个岗位之间有很...
- 前端监控 SDK 开发分享_前端监控系统 开源
-
一、前言随着前端的发展和被重视,慢慢的行业内对于前端监控系统的重视程度也在增加。这里不对为什么需要监控再做解释。那我们先直接说说需求。对于中小型公司来说,可以直接使用三方的监控,比如自己搭建一套免费的...
- Ajax 会被 fetch 取代吗?Axios 怎么办?
-
大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!今天给大家带来的主题是ajax、fetch...
- 前端面试题《AJAX》_前端面试ajax考点汇总
-
1.什么是ajax?ajax作用是什么?AJAX=异步JavaScript和XML。AJAX是一种用于创建快速动态网页的技术。通过在后台与服务器进行少量数据交换,AJAX可以使网页实...
- Ajax 详细介绍_ajax
-
1、ajax是什么?asynchronousjavascriptandxml:异步的javascript和xml。ajax是用来改善用户体验的一种技术,其本质是利用浏览器内置的一个特殊的...
- 6款可替代dreamweaver的工具_替代powerdesigner的工具
-
dreamweaver对一个web前端工作者来说,再熟悉不过了,像我07年接触web前端开发就是用的dreamweaver,一直用到现在,身边的朋友有跟我推荐过各种更好用的可替代dreamweaver...
- 我敢保证,全网没有再比这更详细的Java知识点总结了,送你啊
-
接下来你看到的将是全网最详细的Java知识点总结,全文分为三大部分:Java基础、Java框架、Java+云数据小编将为大家仔细讲解每大部分里面的详细知识点,别眨眼,从小白到大佬、零基础到精通,你绝...
- 福斯《死侍》发布新剧照 "小贱贱"韦德被改造前造型曝光
-
时光网讯福斯出品的科幻片《死侍》今天发布新剧照,其中一张是较为罕见的死侍在被改造之前的剧照,其余两张剧照都是死侍在执行任务中的状态。据外媒推测,片方此时发布剧照,预计是为了给不久之后影片发布首款正式预...
- 2021年超详细的java学习路线总结—纯干货分享
-
本文整理了java开发的学习路线和相关的学习资源,非常适合零基础入门java的同学,希望大家在学习的时候,能够节省时间。纯干货,良心推荐!第一阶段:Java基础重点知识点:数据类型、核心语法、面向对象...
- 不用海淘,真黑五来到你身边:亚马逊15件热卖爆款推荐!
-
Fujifilm富士instaxMini8小黄人拍立得相机(黄色/蓝色)扫二维码进入购物页面黑五是入手一个轻巧可爱的拍立得相机的好时机,此款是mini8的小黄人特别版,除了颜色涂装成小黄人...
- 2025 年 Python 爬虫四大前沿技术:从异步到 AI
-
作为互联网大厂的后端Python爬虫开发,你是否也曾遇到过这些痛点:面对海量目标URL,单线程爬虫爬取一周还没完成任务;动态渲染的SPA页面,requests库返回的全是空白代码;好不容易...
- 最贱超级英雄《死侍》来了!_死侍超燃
-
死侍Deadpool(2016)导演:蒂姆·米勒编剧:略特·里斯/保罗·沃尼克主演:瑞恩·雷诺兹/莫蕾娜·巴卡林/吉娜·卡拉诺/艾德·斯克林/T·J·米勒类型:动作/...
- 停止javascript的ajax请求,取消axios请求,取消reactfetch请求
-
一、Ajax原生里可以通过XMLHttpRequest对象上的abort方法来中断ajax。注意abort方法不能阻止向服务器发送请求,只能停止当前ajax请求。停止javascript的ajax请求...
- 一周热门
- 最近发表
- 标签列表
-
- HTML 简介 (30)
- HTML 响应式设计 (31)
- HTML URL 编码 (32)
- HTML Web 服务器 (31)
- HTML 表单属性 (32)
- HTML 音频 (31)
- HTML5 支持 (33)
- HTML API (36)
- HTML 总结 (32)
- HTML 全局属性 (32)
- HTML 事件 (31)
- HTML 画布 (32)
- HTTP 方法 (30)
- 键盘快捷键 (30)
- CSS 语法 (35)
- CSS 轮廓宽度 (31)
- CSS 谷歌字体 (33)
- CSS 链接 (31)
- CSS 定位 (31)
- CSS 图片库 (32)
- CSS 图像精灵 (31)
- SVG 文本 (32)
- 时钟启动 (33)
- HTML 游戏 (34)
- JS Loop For (32)
