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 2
| npm install --save html2canvas import html2canvas from "html2canvas";
|
示例
1 2 3
| html2canvas(document.querySelector("#capture")).then(canvas => { document.body.appendChild(canvas) });
|
注意
部分样式该组件转换的图片和原样式不同。
如table转换的时候border并不会合并,所以计算坐标的时候要加上间隔的像素,如果是三行那么就要加2像素。
图片无法显示
如果图片没有允许跨域访问,虽然在页面上我们能看到,但是生成Canvas会提示跨域,所以图片必须允许跨域访问,才能正常生成Canvas。
1 2 3 4 5 6 7 8 9 10 11 12 13
| function downQrClick() { let dom = document.querySelector('.qr_page') as HTMLElement if (dom) { html2canvas(dom, { useCORS: true }) .then((canvas) => { let href = canvas.toDataURL() let a = document.createElement('a') a.download = '商品.png' a.href = href a.dispatchEvent(new MouseEvent('click')) }) } }
|
阿里云OSS配置
Canvas合并
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| get_all_page: async function () { let cols = this.cols; let pages = document.querySelectorAll(".page"); var canvas_arr = []; let temp_canvas_arr = []; for (let i = 0; i < pages.length; i++) { const page = pages[i]; let canvas = await html2canvas(page); temp_canvas_arr.push(canvas); if (temp_canvas_arr.length === cols) { var canvas_all = document.createElement("canvas"); let page_width = temp_canvas_arr[0].width; let page_height = temp_canvas_arr[0].height; canvas_all.width = page_width * cols; canvas_all.height = page_height; var context = canvas_all.getContext("2d"); for (let j = 0; j < temp_canvas_arr.length; j++) { const citem = temp_canvas_arr[j]; context.drawImage(citem, j * page_width, 0, page_width, page_height); } canvas_arr.push(canvas_all); temp_canvas_arr = []; } } return canvas_arr; },
|
Canvas下载为图片
1 2 3 4 5 6 7
| html2canvas(document.querySelector(".page")).then(canvas => { let href = canvas.toDataURL() let a = document.createElement('a') a.download = "答题卡.png" a.href = href a.dispatchEvent(new MouseEvent('click')) });
|
图片清晰度设置
html2canvas 提供了一个 scale 选项,通过调整这个比例因子,你可以增加导出图像的分辨率。
默认情况下,scale 为 window.devicePixelRatio,通常等于 1。
你可以将其设置为一个更大的值来增加清晰度。
1 2 3 4 5 6 7 8 9 10 11 12 13
| function downQrClick() { let goodsCode = props.goodsDetail?.goodsCode || ""; let dom = document.querySelector('.qr_page_outer') as HTMLElement if (dom) { html2canvas(dom, { useCORS: true,scale: 2 }).then((canvas) => { let href = canvas.toDataURL() let a = document.createElement('a') a.download = `商品_${goodsCode}.png` a.href = href a.dispatchEvent(new MouseEvent('click')) }) } }
|
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 2
| npm install jspdf --save import jsPDF from 'jspdf';
|
单页下载
示例代码:
1 2 3 4 5 6 7 8 9
| html2canvas(document.querySelector(".page")).then(canvas => { var doc = new jsPDF('portrait', 'mm', 'a4'); doc.addImage(canvas, 'PNG', 0, 0, 210, 297); doc.addPage('a4', 'portrait'); doc.addImage(canvas, 'PNG', 0, 0, 210, 297); doc.save('a4.pdf'); });
|
多页下载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| download_page: async function () { let pages = document.querySelectorAll(".page"); var doc = new jsPDF('portrait', 'mm', 'a4'); for (let i = 0; i < pages.length; i++) { const page = pages[i]; let canvas = await html2canvas(page); if (i !== 0) { doc.addPage('a4', 'portrait'); } doc.addImage(canvas, 'PNG', 0, 0, 210, 297); } doc.autoPrint({ variant: 'non-conform' }); doc.save('autoprint.pdf'); },
|
合并下载
两张A4合并为A3下载
合并
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| get_all_page: async function () { let cols = this.cols; let pages = document.querySelectorAll(".page"); var canvas_arr = []; let temp_canvas_arr = []; for (let i = 0; i < pages.length; i++) { const page = pages[i]; let canvas = await html2canvas(page); temp_canvas_arr.push(canvas); if (temp_canvas_arr.length === cols) { var canvas_all = document.createElement("canvas"); let page_width = temp_canvas_arr[0].width; let page_height = temp_canvas_arr[0].height; canvas_all.width = page_width * cols; canvas_all.height = page_height; var context = canvas_all.getContext("2d"); for (let j = 0; j < temp_canvas_arr.length; j++) { const citem = temp_canvas_arr[j]; context.drawImage(citem, j * page_width, 0, page_width, page_height); } canvas_arr.push(canvas_all); temp_canvas_arr = []; } } return canvas_arr; },
|
下载
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| download_page: async function () { var doc = new jsPDF('landscape', 'mm', 'a3'); let canvas_arr = await this.get_all_page(); for (let i = 0; i < canvas_arr.length; i++) { const canvas = canvas_arr[i]; if (i !== 0) { doc.addPage('a3', 'landscape'); } doc.addImage(canvas, 'PNG', 0, 0, 420, 297); } doc.save('autoprint.pdf'); },
|
方法及参数
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 2 3 4 5 6 7 8 9 10
| html2canvas(document.querySelector(".page")).then(canvas => { var doc = new jsPDF('portrait', 'mm', 'a4'); doc.addImage(canvas, 'PNG', 0, 0, 210, 297); doc.addPage('a4', 'portrait'); doc.addImage(canvas, 'PNG', 0, 0, 210, 297); doc.autoPrint({ variant: 'non-conform' }); doc.save('autoprint.pdf'); });
|
注意这样并不会在下载后自动打印,只是下载的文件被打开时触发打印。
Canvas打印
打印单张
1 2 3 4 5 6 7 8 9 10 11 12
| html2canvas(document.querySelector(".page")).then(canvas => { var dataURL = canvas.toDataURL("image/png"); var printWindow = window.open(); var style = document.createElement('style'); style.innerHTML = "@media print {@page{margin:0;size:210mm 297mm;}}"; printWindow.document.head.appendChild(style); printWindow.document.write('<img src="' + dataURL + '" width="100%" />'); setTimeout(() => { printWindow.print(); printWindow.close(); }, 0); });
|
打印多张
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| print_page: async function () { let pages = document.querySelectorAll(".page"); var printWindow = window.open(); var style = document.createElement('style'); style.innerHTML = "@media print {@page{margin:0;size:420mm 297mm;}}"; printWindow.document.head.appendChild(style); for (let i = 0; i < pages.length; i++) { const page = pages[i]; let canvas = await html2canvas(page); var dataURL = canvas.toDataURL("image/png"); printWindow.document.write('<img src="' + dataURL + '" width="100%" />'); } setTimeout(() => { printWindow.print(); printWindow.close(); }, 0); }
|
打印样式
网页上使用图片打印A3的时候要注意设置以下项,特别是纸张大小和边距,否则跟实际的效果不符合。
页面添加样式
1 2 3 4 5
| @media print { @page{ margin:0;size:420mm 297mm; } }
|
即
1 2 3
| var style = document.createElement('style'); style.innerHTML = "@media print {@page{margin:0;size:420mm 297mm;}}"; printWindow.document.head.appendChild(style);
|
下划线问题
下划线不显示
我们可以使用u标签设置下划线
但是这样在转成Canvas后就会不显示
是因为
html2canvas 在渲染的时候,会把只含空格的元素当作是空元素来处理。
所以我们可以插入不可见元素
1
| <u> ​ ​</u>
|
​是一个 HTML 实体编码,表示 Unicode 中的 零宽空格(Zero Width Space, ZWSP),编码为 U+200B。它是一种不可见的字符,主要用于控制文本的换行或连字行为,而不会在显示时占用实际空间。
下划线预览不一样
默认转成Canvas和HTML中的长度不一样。
设置字体和字体大小即可。
1 2 3 4 5 6
| #content u { font-family: 'Courier New', Courier, monospace; font-size: 12px; min-height: 30px; line-height: 30px; }
|