兼容ie9及以上的截图(基于html2canvas.js)
在公司项目中大胆使用了html5开发,但是偏偏要求兼容ie8以上浏览器,这里不得不骂一句狗日的ie。查了很多资料,发现只有ie9及以上才兼容html2canvas.js,所以我到现在也不知道兼容ie8的截图功能怎么做,若有哪位大神看到帖子,能帮帮忙,小弟感激不尽!!!话不多说,代码贴起。
1、需要导入的js包:jquery-3.2.1.min.js,html2canvas.js,bluebird.js,excanvas.compiled.js
需要的包都放在下面这个链接里了,bluebird.js是为了让ie兼容Promise 对象。
链接:https://pan.baidu.com/s/1h86jSmyTiQcIkfN8100DqQ 密码:agzy
2、前端代码
<html>
<head>
<meta name="layout" content="main">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="../js/jquery-3.2.1.min.js"></script>
<script type="text/javascript" src="../js/html2canvas.js"></script>
<script type="text/javascript" src="../js/bluebird.js"></script>
<!--[if IE]>
<script type="text/javascript" src="../js/html5shiv.min.js"></script>
<script type="text/javascript" src="../js/respond.min.js"></script>
<script type="text/javascript" src="../js/excanvas.compiled.js"></script>
<![endif]-->
<script type="text/javascript" >
function download(){
var oDiv = document.getElementById('pdfDiv');
var width = oDiv.offsetWidth;
var height = oDiv.offsetHeight;
var canvas = document.createElement("canvas");
var scale = 2;
canvas.width = width*scale;
canvas.height = height*scale;
canvas.getContext("2d").scale(scale,scale);
var opts = {
allowTaint:false,
scale:scale,
canvas:canvas,
width:width,
height:height,
useCORS:true
};
var oDivClone = $("#pdfDiv").clone();
var screenDiv = document.createElement("div");
screenDiv.style.cssText = "position:absolute;z-index: -9999;left: 0px;top: 0px;";
$("body").append($(screenDiv));
$(screenDiv).append($(oDivClone));
html2canvas(oDivClone[0],opts).then(function(canvas){
var context = canvas.getContext("2d");
context.mozImageSmoothingEnabled = false;
context.webkitImageSmoothingEnabled = false;
context.msImageSmoothingEnabled = false;
context.imageSmoothingEnabled = false;
var dataUrl = canvas.toDataURL();
if (window.navigator.msSaveOrOpenBlob) {
var blob = canvas.msToBlob();
window.navigator.msSaveBlob(blob,'a.png')
}else{
var a = document.createElement('a')
a.href = dataUrl
a.setAttribute('download', 'a.png')
a.click()
}
$(screenDiv).remove();
});
}
</script>
</head>
<body>
<img id="imgScrd" />
Hello!
<div id="pdfDiv" class="" style="background-color: #abc;">
计算机天堂测试html5页面截图
<br>jsjtt.com
</div>
<textArea id="textArea" col="20" rows="10" ></textArea>
<input class="example1" type="button" onclick="download();" value="button">
生成界面如下:
<div id="ddd" ></div>
<span id="sss"></span>
</body>
</html>
注:html2canvas的参数是dom节点,所以若用jQuery对象需要转成dom节点。若是直接对目标区域截图,当目标的左边,上面有空隙的话,会把空白处也截下;并且还有一种情况,是目标区域是由滚动条的,会导致截图不完整。所以我把目标区域clone一份到一个div中,并且绝对位置,左边上面空白设置为0px,使正确截图到目标区域。
需要注意的是,有些时候截图打开是空白的,此时,你加大width和height,便可以截到。这点我也纳闷了,不知道为啥。
2、目标区域中有自动换行的部分(word-wrap:break-word),在canvas中是不支持的,那我们怎么操作呢?中文的自动换行是可以的,但一长串的英文或者特殊字符字符串就不行了。我能想到的方法是 手动截取,没隔多少位插入
强行换行。
3、这时候我来讨论下兼容性问题,亲测,以上代码在谷歌、ie10以上都是可以的。ie9可以截到图,得到base64代码,但不能用以上两种方法下载到本地了。头大,想了很多办法都不行。看来光靠前端是不行的了,只能去后台转一圈了。把得到的base64代码传到后台,通过java代码解码转换为二进制文件流传到前台下载。
public static boolean Base64ToImage(String imgStr,String imgFilePath) { // 对字节数组字符串进行Base64解码并生成图片
if (StringUtil.isEmpty(imgStr)) // 图像数据为空
return false;
BASE64Decoder decoder = new BASE64Decoder();
try {
// Base64解码
byte[] b = decoder.decodeBuffer(imgStr);
for (int i = 0; i < b.length; ++i) {
if (b[i] < 0) {// 调整异常数据
b[i] += 256;
}
}
OutputStream out = new FileOutputStream(imgFilePath);
out.write(b);
out.flush();
out.close();
return true;
} catch (Exception e) {
return false;
}