现在需要做一个功能:
一个html页面有多个div,每个div里面都含有用echarts画的图表,现在要对这个html页面进行自动截图
我在网上找到了一个方法:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>htmltopic</title>
<script type="text/javascript" src="js/jquery-2.2.1.min.js"></script>
<script type="text/javascript" src="js/html2canvas.min.js"></script>
<style>
* {
margin: 0;
}
.main{
height: 100%;
width: 100%;
}
body{
background-color: #2e6da4;
}
.test1 {
width: 50%;
height: 100%;
text-align: center;
line-height: 100px;
/*background-color: #87CEEB;*/
display: inline-block;
vertical-align: top;
}
canvas {
/*margin-right: 5px;*/
}
.down {
float: left;
margin: 40px 10px;
}
.down2 {
float: left;
margin: 40px 30px;
}
</style>
</head>
<body id="test">
<div class="main">
<div class="test1" >测试</div>
<div class="test1" >测试</div>
<!--<div class="test1" id="test1">测试</div>-->
</div>
<div><a class="down" href="" download="downImg">下载</a>
</div>
<div><a class="down2" href="" download="downImg">下载2</a></div>
<script>
//直接选择要截图的dom,就能截图,但是因为canvas的原因,生成的图片模糊
//html2canvas(document.querySelector('div')).then(function(canvas) {
// document.body.appendChild(canvas);
//});
//创建一个新的canvas
var canvas2 = document.createElement("canvas");
let
_canvas = document.querySelector('#test');
var w = parseInt(window.getComputedStyle(_canvas).width);
var h = parseInt(window.getComputedStyle(_canvas).height);
//将canvas画布放大若干倍,然后盛放在较小的容器内,就显得不模糊了
canvas2.width = w * 2;
canvas2.height = h * 2;
canvas2.style.width = w + "px";
canvas2.style.height = h + "px";
//可以按照自己的需求,对context的参数修改,translate指的是偏移量
// var context = canvas.getContext("2d");
// context.translate(0,0);
var context = canvas2.getContext("2d");
context.scale(2, 2);
html2canvas(document.querySelector('#test'), { canvas: canvas2 }).then(function(canvas) {
//document.body.appendChild(canvas);
//canvas转换成url,然后利用a标签的download属性,直接下载,绕过上传服务器再下载
document.querySelector(".down").setAttribute('href', canvas.toDataURL());
});
</script>
<script language="javascript">
//这是另一种写法
$(function () {
$(".down2").click(function () {
html2canvas($("#test")).then(function (canvas) {
var imgUri = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream"); // 获取生成的图片的url
window.location.href = imgUri; // 下载图片
});
//html2canvas($('.tongxingzheng_bg'), {
// onrendered: function (canvas) {
// var data = canvas.toDataURL("image/png");//生成的格式
// //data就是生成的base64码啦
// alert(data);
// }
//});
});
});
</script>
</body>
</html>
截的图如下:
问题来了,上面只是简单地html页面,当我在html页面放echarts时,就出现问题了
html代码
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="zh-CN">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <!-- 在IE运行最新的渲染模式 -->
<meta name="viewport" content="width=device-width, initial-scale=1"> <!-- 初始化移动浏览显示 -->
<meta name="Author" content="Dreamer-1.">
<script src="js/jquery.min.js"></script>
<script src="js/echarts-all.js"></script>
<script type="text/javascript" src="js/jquery-2.2.1.min.js">
</script><script type="text/javascript" src="js/html2canvas.min.js"></script>
<!-- <script src="js/echarts.min.js"></script> -->
<title>生成图片测试2</title>
<style>
body{
background-color: #2e6da4;
}
</style>
</head>
<body>
<div><a class="down" href="" download="downImg">下载</a></div>
<div><a class="down2" href="" download="downImg">下载2</a></div>
<!-- 显示Echarts图表 -->
<div style="height:410px;min-height:100px;margin:0 auto;" id="main"></div>
<script type="text/javascript">
var data = ["9","19","29","39","49","59"];
var barText = "初始化完毕";
var barSubtext = "副标题";
var xData = ["衬衫","羊毛衫","雪纺衫","裤子","高跟鞋","袜子"];
var legendValue = ['销量','销量2'];
var seriesName1 = '销量';
var seriesName2 = '销量2';
var worldMapContainer = document.getElementById('main')
var resizeWorldMapContainer = function () {
worldMapContainer.style.width = window.innerWidth+'px';
worldMapContainer.style.height = window.innerHeight+'px';
};
//设置容器高宽
// resizeWorldMapContainer();
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(worldMapContainer);
var option = {
title : {
text : barText,
subtext: barSubtext
},
tooltip : {},
legend : {
data : legendValue
},
xAxis : {
data : xData,
type : 'category'
},
yAxis : {},
color: ['#ddffee', '#00ffff'],
series : [ {
name : seriesName1,
type : 'bar',
data : data , //该位置放的是一个数组
barWidth: 50,
/* itemStyle:{
normal:{
color:'#ddffee'
}
}, */
label:{
normal:{
show:true,
position:'top'
}
},
} ,
{
name : seriesName2,
type : 'bar',
data : data , //该位置放的是一个数组
barWidth: 50,
/* itemStyle:{
normal:{
color:'#00ffff'
}
}, */
label:{
normal:{
show:true,
position:'top'
}
},
}]
};
myChart.setOption(option); //载入图表
//用于使chart自适应高度和宽度
window.onresize = function () {
//重置容器高宽
resizeWorldMapContainer();
myChart.resize();
};
window.onload = addSaveImageUrl;
function addSaveImageUrl() {
var canvas2 = document.createElement("canvas"); //创建一个新的canvas
let _canvas = document.querySelector('#main'); //这里面填写 你需要截图的div
var w = parseInt(window.getComputedStyle(_canvas).width);
var h = parseInt(window.getComputedStyle(_canvas).height);
canvas2.width = w * 2;
canvas2.height = h * 2; //将canvas画布放大2倍或者更多,然后盛放在较小的容器内,就显得不模糊了
canvas2.style.width = w + "px";
canvas2.style.height = h + "px";
var context = canvas2.getContext("2d");
context.scale(2, 2); //指图片偏移
html2canvas(document.querySelector('#main'), { //写需要截图的div
taintTest: false,
useCORS: true,
allowTaint: false, //这三串代码解决跨域问题
canvas: canvas2
}).then(
function (canvas) {
document.querySelector(".down").setAttribute('href', canvas.toDataURL()); //down设置为你的点击键
});
}
</script>
</body>
</html>
页面效果:
截的图如下:
先不考虑后面马赛克的问题,发现用echarts时,截的图片只是一部分,其余部分是空白
然后我用谷歌浏览器、火狐浏览器都试了,谷歌从始至终截的图都如上图所示,火狐第一次加载页面截图如下所示,但是刷信页面之后截的图和谷歌截的图一样了。
在网上找了一下原因,这是因为跨域问题
因为我的网页里面的图表不是来自我的服务器,而是来自echarts组件的。那么这些图表就和这个网页不是同域,那么html2canvas就无法对这个网页进行进图。如果我的网页所有的东西都放在单独的服务器上,那么用html2canvas对整个网页进行截图就会发现所有的图片的地方都是空白。
问题先记录下来,解决问题之后进行更更新
折腾了三天左右的时间,中间有请教大神,大神还不相信我会做出来,结果让他失望了,哈哈哈
下面详细说一下怎么解决的
我的html页面放了多个echarts图,我要将该页面生成一个图片,现在的思路是
1、将所有图表放在一个大的div里面
2、在echarts的渲染结束事件中将画布的url赋给页面中没有src值得img标签
实现的代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title></title>
<link href="css/bootstrap.css" rel="stylesheet">
<link rel="stylesheet" href="css/base.css">
<link rel="stylesheet" href="css/index.css">
<script type="text/javascript" src="js/html2canvas.min.js"></script>
<style>
.t_title {
width: 100%;
height: 100%;
text-align: center;
font-size: 2.5em;
line-height: 80px;
color: #fff;
}
#chart_map {
cursor: pointer;
}
.t_show {
position: absolute;
top: 0;
right: 0;
border-radius: 2px;
background: #2C58A6;
padding: 2px 5px;
color: #fff;
cursor: pointer;
}
</style>
</head>
<body>
<div id="main">
<!--header-->
<div class="header">
<div class="bg_header">
<div class="header_nav fl t_title">
</div>
</div>
</div>
<!--main-->
<div class="data_content">
<div class="data_time">
</div>
<div class="data_main">
<!-- 左侧部分 -->
<div class="main_left fl">
<div class="left_1 t_btn6" style="cursor: pointer;">
<!--左上边框-->
<div class="t_line_box">
<i class="t_l_line"></i>
<i class="l_t_line"></i>
</div>
<!--右上边框-->
<div class="t_line_box">
<i class="t_r_line"></i>
<i class="r_t_line"></i>
</div>
<!--左下边框-->
<div class="t_line_box">
<i class="l_b_line"></i>
<i class="b_l_line"></i>
</div>
<!--右下边框-->
<div class="t_line_box">
<i class="r_b_line"></i>
<i class="b_r_line"></i>
</div>
<div class="main_title" id="title_1" >
<!-- <img src="images/t_1.png" alt=""> -->
</div>
<div id="char_bar" class="chart" style="width:100%;height: 280px;"></div>
</div>
<div class="left_2" style="cursor: pointer;">
<!--左上边框-->
<div class="t_line_box">
<i class="t_l_line"></i>
<i class="l_t_line"></i>
</div>
<!--右上边框-->
<div class="t_line_box">
<i class="t_r_line"></i>
<i class="r_t_line"></i>
</div>
<!--左下边框-->
<div class="t_line_box">
<i class="l_b_line"></i>
<i class="b_l_line"></i>
</div>
<!--右下边框-->
<div class="t_line_box">
<i class="r_b_line"></i>
<i class="b_r_line"></i>
</div>
<div class="main_title" id="title_2">
<!-- <img src="images/t_2.png" alt=""> -->
</div>
<div id="chart_2" class="chart t_btn9" style="width:100%;height: 280px;"></div>
</div>
</div>
<!-- 中间部分 -->
<div class="main_center fl">
<div class="center_text">
<!--左上边框-->
<div class="t_line_box">
<i class="t_l_line"></i>
<i class="l_t_line"></i>
</div>
<!--右上边框-->
<div class="t_line_box">
<i class="t_r_line"></i>
<i class="r_t_line"></i>
</div>
<!--左下边框-->
<div class="t_line_box">
<i class="l_b_line"></i>
<i class="b_l_line"></i>
</div>
<!--右下边框-->
<div class="t_line_box">
<i class="r_b_line"></i>
<i class="b_r_line"></i>
</div>
<div class="main_title" id="title_3">
<!-- <img src="images/t_3.png" alt=""> -->
</div>
<div id="chart_map" style="width:100%;height:610px;"></div>
</div>
</div>
<!-- 右侧部分 -->
<div class="main_right fr">
<div class="right_1">
<!--左上边框-->
<div class="t_line_box">
<i class="t_l_line"></i>
<i class="l_t_line"></i>
</div>
<!--右上边框-->
<div class="t_line_box">
<i class="t_r_line"></i>
<i class="r_t_line"></i>
</div>
<!--左下边框-->
<div class="t_line_box">
<i class="l_b_line"></i>
<i class="b_l_line"></i>
</div>
<!--右下边框-->
<div class="t_line_box">
<i class="r_b_line"></i>
<i class="b_r_line"></i>
</div>
<div class="main_title" id="title_4">
<!-- <img src="images/t_4.png" alt=""> -->
</div>
<div id="chart_4" class="echart t_btn7" style="width:100%;height: 280px;"></div>
</div>
<div class="right_2">
<!--左上边框-->
<div class="t_line_box">
<i class="t_l_line"></i>
<i class="l_t_line"></i>
</div>
<!--右上边框-->
<div class="t_line_box">
<i class="t_r_line"></i>
<i class="r_t_line"></i>
</div>
<!--左下边框-->
<div class="t_line_box">
<i class="l_b_line"></i>
<i class="b_l_line"></i>
</div>
<!--右下边框-->
<div class="t_line_box">
<i class="r_b_line"></i>
<i class="b_r_line"></i>
</div>
<div class="main_title" id="title_5">
<!-- <img src="images/t_7.png" alt=""> -->
</div>
<div id="chart_5" class="echart fl t_btn4" style="width:100%;height: 280px;cursor: pointer;"></div>
</div>
</div>
</div>
</div>
</div>
<img alt="" src="" id="testImage">
</body>
<script src="js/jquery-2.2.1.min.js"></script>
<script src="js/bootstrap.min.js"></script>
<script src="js/common.js"></script>
<script src="js/echarts.min.js"></script>
<script src="template/bar.js"></script>
<script src="template/line.js"></script>
<script src="template/pie.js"></script>
<script type="text/javascript">
myChart.on('rendered', function () {
/* console.log($("canvas")[0].toDataURL());
document.querySelector("#testImage").setAttribute('src', $("canvas")[0].toDataURL()); */
var canvas2 = document.createElement("canvas"); //创建一个新的canvas
let _canvas = document.querySelector('#main'); //这里面填写 你需要截图的div
var w = parseInt(window.getComputedStyle(_canvas).width);
var h = parseInt(window.getComputedStyle(_canvas).height);
canvas2.width = w;
canvas2.height = h; //将canvas画布放大2倍或者更多,然后盛放在较小的容器内,就显得不模糊了
canvas2.style.width = w + "px";
canvas2.style.height = h + "px";
// canvas.width = parseInt(canvas.style.width)*2;
// canvas.height = parseInt(canvas.style.height)*2;
// canvas.style.height = canvas.height/2 + "px";
// canvas.style.width = canvas.width/2 + "px";
var context = canvas2.getContext("2d");
context.scale(1, 1); //指图片偏移
html2canvas(document.querySelector('#main'), { //写需要截图的div
taintTest: false,
useCORS: true,
allowTaint: false, //这三串代码解决跨域问题
canvas: canvas2
}).then(
function (canvas) {
console.log(canvas.toDataURL());
document.querySelector("#testImage").setAttribute('src', canvas.toDataURL());
});
});
</script>
<!-- <script src="js/dataTool.js"></script>
<script src="js/index.js"></script>
<script src="js/china.js"></script> -->
</html>
图片生成实现了,现在想想项目的业务是要在后台生成图片,我的思路是
既然将canvas.toDataURL()赋给一个img标签的src,它就可以展示成一个图片,那我可以将这个值存到后台,将来展示的时候拿到前台放到img标签里面就可以了
参考: