前言
前文说了如何识别答题卡,本文来说说怎么生成答题卡。
OpenCV可以用来生成,但是文字换行等场景就比较难实现,这里使用HTML生成答题卡。
A3/A4尺寸
A4 210mm×297mm
A3 420mm×297mm
HTML转Canvas
虽然OpenCV可以用来绘图 但是制作答题卡的时候还是建议使用HTML来实现,并用html2canvas
转为图片。
http://html2canvas.hertzen.com/
https://www.bootcdn.cn/html2canvas/
添加引用
1 | <script src="https://cdn.bootcdn.net/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script> |
或者
1 | npm install --save html2canvas |
示例
1 | html2canvas(document.querySelector("#capture")).then(canvas => { |
注意
部分样式该组件转换的图片和原样式不同。
如table转换的时候border并不会合并,所以计算坐标的时候要加上间隔的像素,如果是三行那么就要加2像素。
Canvas合并
1 | get_all_page: async function () { |
Canvas下载为图片
1 | html2canvas(document.querySelector(".page")).then(canvas => { |
Canvas下载为PDF
https://artskydj.github.io/jsPDF/docs/index.html
图片生成PDF
添加引用
1 | <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.5.3/jspdf.debug.js" integrity="sha384-NaWTHo/8YCBYJ59830LTz/P4aQZK1sS0SneOgAvhsIl3zBu8r9RevNg5lHCHAuQ/" crossorigin="anonymous"></script> |
或者
1 | npm install jspdf --save |
单页下载
示例代码:
1 | html2canvas(document.querySelector(".page")).then(canvas => { |
多页下载
1 | download_page: async function () { |
合并下载
两张A4合并为A3下载
合并
1 | get_all_page: async function () { |
下载
1 | download_page: async function () { |
方法及参数
jsPDF()
Name | Type | Default | Description |
---|---|---|---|
orientation |
string | portrait |
方向 “portrait” or “landscape” (or shortcuts “p” or “l”). |
unit |
string | mm |
单位 “pt” (points), “mm”, “cm”, “m”, “in” or “px”. |
format |
string/Array | a4 |
首页的大小 可以使用:a0 - a10 b0 - b10 c0 - c10 默认为”a4”. 也可以使用具体的大小数组 如: [595.28, 841.89] |
添加图片
注意添加图片前一定要先添加页面。
addImage(imageData, format, x, y, width, height, alias, compression, rotation)
Parameters:
Name | Type | Description | |||
---|---|---|---|---|---|
imageData |
string \ | HTMLImageElement \ | HTMLCanvasElement \ | Uint8Array | imageData as base64 encoded DataUrl or Image-HTMLElement or Canvas-HTMLElement |
format |
string | format of file if filetype-recognition fails, e.g. ‘JPEG’ | |||
x |
number | x Coordinate (in units declared at inception of PDF document) against left edge of the page | |||
y |
number | y Coordinate (in units declared at inception of PDF document) against upper edge of the page | |||
width |
number | width of the image (in units declared at inception of PDF document) | |||
height |
number | height of the Image (in units declared at inception of PDF document) | |||
alias |
string | alias of the image (if used multiple times) | |||
compression |
string | compression of the generated JPEG, can have the values ‘NONE’, ‘FAST’, ‘MEDIUM’ and ‘SLOW’ | |||
rotation |
number | rotation of the image in degrees (0-359) |
下载后自动打印
下载后的文件打开时自动调用打印
1 | html2canvas(document.querySelector(".page")).then(canvas => { |
注意这样并不会在下载后自动打印,只是下载的文件被打开时触发打印。
Canvas打印
打印单张
1 | html2canvas(document.querySelector(".page")).then(canvas => { |
打印多张
1 | print_page: async function () { |
打印样式
网页上使用图片打印A3的时候要注意设置以下项,特别是纸张大小和边距,否则跟实际的效果不符合。
页面添加样式
1 | @media print { |
即
1 | var style = document.createElement('style'); |
获取DIV坐标
绝对位置
网页元素的绝对位置,指
该元素的左上角相对于整张网页左上角的坐标
。
首先,每个元素都有offsetTop和offsetLeft属性,表示该元素的左上角与父容器(offsetParent对象)左上角的距离。所以,只需要将这两个值进行累加,就可以得到该元素的绝对坐标。但这里要注意一个问题:要考虑offsetParent的border的宽度。
方式1
1 | // 得到对象的相对浏览器的坐标 |
注意
一定要添加父元素的Border的宽度(clientLeft)。
隐藏的元素要用
opacity: 0;
,不能用display: none;
,否则获取不了位置。这种方式不是特别精确,如果dom的宽高不是整数的时候会出现偏差。
运算效率也相对较低。
方式2
这种方式要注意滚动条所在的DOM是那个。
1 | export function getObjPos(_target, scroll_dom) { |
注意
隐藏的元素要用
opacity: 0;
,不能用display: none;
,否则获取不了位置。运算效率相对高点。
相对位置
网页元素的相对位置,指该元素左上角
相对于浏览器窗口左上角的坐标
。
方法1
获取元素的相对位置,JS还提供了一种更简单的方法:Element.getBoundingClientRect()
Element.getBoundingClientRect()返回一个对象,对象包含了元素距离窗口的位置属性:left、right、top、bottom
1 | let odiv = document.querySelector(".div2"); |
方法2
有了绝对位置以后,获得相对位置就很容易了,只要将绝对坐标减去页面的滚动条滚动的距离就可以了。
1 | function getObjPosR (element) { |
PX和MM互转
方式1
1 | function unitUtil () { |
调用
1 | new unitUtil().px2mm(width) |
方式2
1 | function unitConversion () { |
调用
1 | new unitConversion().px2mm(width) |