使用JavaScript库构建Webscript以生成手写的PDF文件
在本教程中,我们将学习如何使用开源的JavaScript库将网页转换成PDF文档。手签是认证官方文件的一个好方法。
如果有关各方相距甚远怎么办?我们必须想办法让他们能够在线签署文件。
好在,我们可以使用一个名为Signature Pad的开源JavaScript库,不费吹灰之力就能在我们的Web应用程序中做到这一点。
我们将建立一个简单的发票,其中有一个嵌入的部分,一个人的签名将在签署后出现。稍后,我们将使用另一个名为jsPDF的开源库将网页转换为PDF文档。
我们的最终输出应该是这样的。

前提条件
作为先决条件,读者必须具备以下条件。
- 对HTML和CSS的理解。
- 对JavaScript和文档对象操作(DOM)的了解。
目标
我们将学习。
- 为网络应用程序创建一个签名功能。
- 使用jsPDF库生成PDF。
- 将生成的签名转换为图像。
这两个库的概述
签名板
签名板允许我们在画布元素上绘制平滑的曲线。这种能力使它适合于为终端用户创建一个签名板。
签名板提供了撤销、清除、改变曲线颜色、将签名转换为不同的图像格式,如.png 、.jpeg 、.svg ,等等的功能。
在我们的文章中,我们将把签名转换为.png 图像。
jsPDF
jsPDF用于从网页中生成一个PDF文档。它提供了设置字体类型、字体大小、线宽、文本颜色等选项。
然而,我们不会深入研究它的用途。我们将简单地用它来生成一个PDF。我将把其他功能留给你,让你通过结尾处的链接进行研究。
就这样,让我们首先设计一个页面的布局。
实施
页面布局
在本教程中,我们将使用Bootstrap库来设计网页。
我们将使用的主要Bootstrap样式类是。
col-md-*一个页面的网格划分。这种风格设计将一个页面分成12列。例如,如果你想让某个元素覆盖页面宽度的三分之一,你可以使用 类。col-md-4d-flex- 这允许我们使一个元素符合CSS的flexbox属性,我们将使用justify-content-*定位来安排页面上的项目。如果我们想让div的元素处于中心位置,我们将使用d-flex justify-content-center类。
让我们简单地看一下这些组件。
<head> 将字符代码设置为UTF-8 ,页面的标题,以及链接到Bootstrap的风格设计。
<head>
<meta charset="utf-8" />
<title>Signature pad HTML2PDF</title>
<link
rel="stylesheet"
href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
crossorigin="anonymous"
/>
</head>
我们前往<body> 部分,其中有几个<div> 元素,我们将只看其中重要的元素。
我们将
onselectstart属性设置为返回false,这样我们就可以只在我们的canvas上进行选择。
- 第二个
<div>,包含表格和签名出现的区域。
<div id="toPrint" class="col-md-12">
<table class="table">
<thead class="thead-dark">
<tr>
<th scope="col"></th>
<th scope="col">Item</th>
<th scope="col">Price</th>
<th scope="col">Quantity</th>
<th scope="col">Price</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">1</th>
<td>Toothbrush</td>
<td>KES. 180</td>
<td>3</td>
<td>KES. 540</td>
</tr>
<tr>
<th scope="row">2</th>
<td>Toothpaste</td>
<td>KES. 560</td>
<td>1</td>
<td>KES. 560</td>
</tr>
<tr>
<th scope="row">3</th>
<td>Cookies</td>
<td>KES. 120</td>
<td>2</td>
<td>KES. 240</td>
</tr>
<tr>
<th scope="row"></th>
<td></td>
<td></td>
<th class="text-danger">GRAND TOTAL</th>
<td>KES. 1340</td>
</tr>
</tbody>
</table>
<div class="col-md-12 d-flex justify-content-end">
<div class="col-md-3 d-flex justify-content-center">
<span class=" mb-4">Your Signature</span>
</div>
</div>
<div class="col-md-12 d-flex justify-content-end">
<div class="col-md-3 d-flex justify-content-center">
<img
id="signature"
style="border: 1px solid black;"
width="250px"
height="100px"
/>
</div>
</div>
</div>
- 下一个
div,包含画布元素,我们允许用户在这里画出签名。
<div class="col-md-12 d-flex justify-content-center ">
<span class="col-md-3 mb-4">Sign here</span>
</div>
<div class="col-md-12 d-flex justify-content-center ">
<canvas
id="canvas"
height="500"
width="800"
style="border: 1px solid black"
></canvas>
</div>
- 最后一个
div,包含四个动作按钮,用于处理签名(Save),清除签名(Clear),撤销签名(Undo),以及生成PDF文档(Get PDF),点击即可。
<div class="col-md-12 d-flex justify-content-around ">
<button
type="button"
style="margin-top: 2%; margin-bottom: 3%"
class="btn btn-dark"
data-action="action-save"
>
Save
</button>
<button
type="button"
style="margin-top: 2%; margin-bottom: 3%"
class="btn btn-dark"
data-action="action-undo"
>
Undo
</button>
<button
type="button"
style="margin-top: 2%; margin-bottom: 3%"
class="btn btn-dark"
data-action="action-clear"
>
Clear
</button>
<button
type="button"
style="margin-top: 2%; margin-bottom: 3%"
class="btn btn-dark"
data-action="action-pdf"
>
Get PDF
</button>
</div>
注意脚本和样式标签,我们将在这里引用JavaScript和Bootstrap的样式文件。
在下一节中,我们将看看我们如何在按钮点击后用JavaScript执行动作。
JavaScript代码
你可以创建一个文件,并将其命名为sign-handler.js 或任何其他名称,只要你更新HTML代码的脚本引用。
我们将首先初始化用于访问DOM元素的变量。
var canvas = document.getElementById("canvas");
var saveSignBtn = document.querySelector("[data-action=action-save]");
var undoBtn = document.querySelector("[data-action=action-undo]");
var clearBtn = document.querySelector("[data-action=action-clear]");
var createPDFBtn = document.querySelector("[data-action=action-pdf]");
- 接下来,我们初始化我们的
SignaturePad类,同时我们传入背景颜色为白色,并将画布设置为2D上下文。
var ourPad = new SignaturePad(canvas, {
backgroundColor: "rgb(255, 255, 255)",
});
canvas.getContext("2d");
- 之后,我们创建一个函数来创建一个blob。我们使用blob来获得一个图像路径,在这里我们设置图像的
src。
function processImage() {
//creating a blob and displaying the image in the image element
canvas.toBlob(function (blob) {
var targetImg = document.querySelector("img"),
url = URL.createObjectURL(blob);
targetImg.src = url;
});
}
- 接下来的三个函数是直接的。它们是为了给三个按钮添加点击事件监听器。
saveSignBtnclearBtnundoBtn
- 对于
undo按钮,我们使用pop()函数删除画在画布上的最后一个点或曲线,然后使用fromData()方法更新画布。
saveSignBtn.addEventListener("click", function (event) {
if (ourPad.isEmpty()) {
alert("Please sign first.");
} else {
processImage();
}
});
//clearing the signature drawing
clearBtn.addEventListener("click", function (event) {
if (ourPad.isEmpty()) {
alert("Please sign first.");
} else {
ourPad.clear();
}
});
undoBtn.addEventListener("click", function (event) {
var signMark = ourPad.toData();
if (ourPad.isEmpty()) {
alert("Please sign first.");
} else {
if (signMark) {
signMark.pop(); // deletinging the last marked dot or drawn line
ourPad.fromData(signMark);
}
}
});
- 最后,我们有按钮点击监听器函数来生成一个PDF文档。
//creating a pdf using the jsPDF library
createPDFBtn.addEventListener("click", function (event) {
window.html2canvas = html2canvas;
window.jsPDF = window.jspdf.jsPDF;
var doc = new jsPDF("l", "pt", "a4");
doc.html(document.getElementById("toPrint"), {
callback: function (doc) {
doc.save();
},
x: 10,
y: 10,
});
});
上面的代码做了以下工作。
- 我们初始化
html2canvas和jsPDF库。 - 如果你想知道为什么我们要初始化
html2canvas,jsPDF库用它来捕捉页面的截图。 jsPDF构造函数会传入方向(l为横向)、测量单位(pt为点)和A4尺寸。我们为我们的页面选择了横向纵向,以适应PDF文档。html()函数被调用,在这里我们传入要打印的元素和一个options对象。- 该对象包含一个
save()回调函数,以保存PDF文档的X和Y定位。还有一堆其他选项,你可以添加到这个对象中。
结论
最后,我们看了这两个库的概述,创建了一个HTML布局,并看了JavaScript代码。
你可以进一步加强这个签名功能,并将其用于生物识别认证。签名板库在你的React-Native应用、Web框架(如Express)、甚至桌面应用中都非常有用。