最近在搞一个项目,用户需要截图datatable表格,表格出现滚动条时,用户需要滚动表格并截图多次,截图大小不一,比较麻烦,于是我实现一键生成html任意元素截图的功能,对于出现滚动条看不见的元素也能生成图片,示例代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.3.3/html2canvas.min.js"></script>
<title>Canvas to Image</title>
</head>
<body>
<div id="mydiv" style="background-color:yellow">1</div>
<div id="mydiv2" style="background-color:red">2</div>
<div id="mydiv3" style="background-color:black">3</div>
<div id="mydiv4" style="background-color:purple">4</div>
<button id="pic_btn">Convert to Image</button>
<script>
$("#pic_btn").click(function(){
convert_elements_to_image_and_download(["#mydiv", "#mydiv2", "#mydiv3", "#mydiv4"]);
})
async function convert_elements_to_image_and_download(array_ele_selectors, is_vertical=true) {
// 元素img data保存列表
let array_ele_img_datas = new Array();
// 元素img 宽度保存列表
let array_ele_img_widths = new Array();
// 元素img 高度保存列表
let array_ele_img_heights = new Array();
for(let i=0; i < array_ele_selectors.length; i++){
let selector = document.querySelector(array_ele_selectors[i]);
array_ele_img_datas.push(await generate_img_data(selector));
array_ele_img_widths.push(get_ele_width(selector));
array_ele_img_heights.push(get_ele_height(selector));
}
let img_data = null;
if(is_vertical){
//垂直排列合并元素图片
img_data = await vertical_merge_elements_pic(
array_ele_img_datas,
array_ele_img_widths,
array_ele_img_heights);
}else{
console.log("Not support yet!");
return false;
}
download_picture(img_data);
}
async function vertical_merge_elements_pic(array_ele_img_datas,
array_ele_img_widths,
array_ele_img_heights){
// 垂直方向合并各个元素图片
let total_height = 0;
let max_width = 0;
for(let i=0; i < array_ele_img_datas.length; i++){
total_height += array_ele_img_heights[i];
if(max_width < array_ele_img_widths[i]){
max_width = array_ele_img_widths[i];
}
}
// 创建canvas元素
var canvas = document.createElement('canvas');
// 设置canvas的宽高
canvas.width = max_width;
canvas.height = total_height;
// 获取canvas的2D绘图上下文
var ctx = canvas.getContext('2d');
//在canvas上绘制图片
let already_have_height = 0;
for(var j=0;j<array_ele_img_datas.length;j++){
await new Promise((resolve, reject) => {
let tmp_img = new Image();
tmp_img.onload = () => {
ctx.drawImage(tmp_img, 0, already_have_height);
resolve();
};
tmp_img.onerror = reject;
tmp_img.src = array_ele_img_datas[j];
});
already_have_height += array_ele_img_heights[j];
}
// 返回合并后的图片
return canvas.toDataURL();
}
function get_ele_width(element){
//获取元素宽度
return element.clientWidth;
}
function get_ele_height(element){
//获取元素高度
return element.clientHeight;
}
async function generate_img_data(element) {
//返回的是图片base64编码
try {
// html2canvas是异步执行的
// 使用await关键字等待html2canvas的Promise完成
const canvas = await html2canvas(element);
console.log("Canvas generated:", canvas);
return canvas.toDataURL();
} catch (error) {
console.error('Error generating canvas:', error);
}
}
function download_picture(data_url){
// 创建一个a标签用于下载
const a = document.createElement('a');
a.href = data_url;
// 设置下载的文件名
a.download = 'screenshot.png';
// 触发点击事件
a.click();
}
</script>
</body>
</html>