公司要求将一些重要数据全部以图片的形式放在官网上,防止网络爬虫。
之前都是UI作图,人工上传,为了解放生产力,于是我们程序处理。
步骤:
1、html得到与原图一致的图片(交给前端处理)
2、html转png
3、配置动态html转动态png,放到对应位置
解决过程:
1、百度找插件
2、百度找插件
3、问人
4、研究替换使用
方案一:
html2canvas插件
官网地址:
http://html2canvas.hertzen.com/
使用例子:
<html><head> ?<meta charset="UTF-8"> ?<meta name="viewport" content="width=device-width, initial-scale=1.0"> ?<meta http-equiv="X-UA-Compatible" content="ie=edge"> ?<title></title><style>.main{ ?width: 900px; ?margin: 2rem auto; ?padding: 2rem 3rem; ?box-shadow: 0 0 23px #ddd6;}h1{ ?text-align: center; ?font-size: 32px; ?color: #3e3e3e;}h1 span{ ?text-align: center; ?font-size: 16px; ?color: #ddd; ?display: block;}h2{ ?border-left: 5px solid #ff6a00; ?padding-left: 11px; ?font-size: 28px; ?font-weight: normal; ?line-height: 25px; ?margin-bottom: 50px; ?margin-top: 40px;}.box{ ?width: 20%; ?box-shadow: 0 0 22px rgba(221, 221, 221, 0.65); ?height: 6rem; ?padding: 1rem; ?font-size: 29px; ?text-align: center; ?margin-right: ?1%; ?display: inline-block; ?margin-bottom: 2%;}.box em{ ?font-weight: bold; ?font-style: normal; ?display: block; ?line-height: 1.5rem; ?margin-top: 1rem; ?font-size: 27px;}.box span{ ?font-size: 14px; ?color: #bdbdbd;}.clear{ ?clear: both; ?visibility: hidden;}</style><script type="text/javascript" src="jquery.min.js"></script><script type="text/javascript" src="html2cavas.js"></script><script type="text/javascript">$(function(){ ?????$("#saveImg").click(function(){ ??????????html2canvas($(".main")[0]).then(function(canvas) { ??????????????var imgUri = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream"); ?????????????//alert(imgUri); ????????????// 获取生成的图片的url ????????????window.location.href= imgUri; // 下载图片 ??????????}); ??????}); ?}); ?</script></head><body><div class=‘main‘> ?<h1>蚂米平台实时运营数据 ???<span>数据统计截止时间:2018-05-27</span> ?</h1> ?<div> ???<h2>交易数据</h2> ???<h3>数据概览</h3> ???<div class=‘box‘> ?????<em>204571155.20</em> ?????<span>累计借贷金额(元)</span> ???</div> ???<div class=‘box‘> ?????<em>204571155.20</em> ?????<span>累计借贷金额(元)</span> ???</div> ???<div class=‘box‘> ?????<em>204571155.20</em> ?????<span>累计借贷金额(元)</span> ???</div> ???<div class=‘box‘> ?????<em>204571155.20</em> ?????<span>累计借贷金额(元)</span> ???</div> ???<div class=‘box‘> ???????<em>204571155.20</em> ???????<span>累计借贷金额(元)</span> ?????</div> ???????<div class=‘box‘> ???????<em>204571155.20</em> ???????<span>累计借贷金额(元)</span> ?????</div> ???????<div class=‘box‘> ???????<em>204571155.20</em> ???????<span>累计借贷金额(元)</span> ?????</div> ???????<div class=‘box‘> ???????<em>204571155.20</em> ???????<span>累计借贷金额(元)</span> ?????</div> ???????????<h3>数据概览</h3> ?????<div class=‘box‘> ???????<em>204571155.20</em> ???????<span>累计借贷金额(元)</span> ?????</div> ?????<div class=‘box‘> ???????<em>204571155.20</em> ???????<span>累计借贷金额(元)</span> ?????</div> ?????<div class=‘box‘> ???????<em>204571155.20</em> ???????<span>累计借贷金额(元)</span> ?????</div> ?????<div class=‘box‘> ???????<em>204571155.20</em> ???????<span>累计借贷金额(元)</span> ?????</div> ?????<div class=‘box‘> ???????<em>204571155.20</em> ???????<span>累计借贷金额(元)</span> ?????</div> ?????<h2>出借方和借款方信息</h2> ?????<div class=‘box‘> ?????????<em>204571155.20</em> ?????????<span>累计借贷金额(元)</span> ???????</div> ?????????<div class=‘box‘> ?????????<em>204571155.20</em> ?????????<span>累计借贷金额(元)</span> ???????</div> ?????????<div class=‘box‘> ?????????<em>204571155.20</em> ?????????<span>累计借贷金额(元)</span> ???????</div> ???????<div class=‘clear‘></div> ???????<div class=‘box‘> ???????????<em>204571155.20</em> ???????????<span>累计借贷金额(元)</span> ?????????</div> ?????????????<div class=‘box‘> ???????????<em>204571155.20</em> ???????????<span>累计借贷金额(元)</span> ?????????</div> ?????????????<div class=‘box‘> ???????????<em>204571155.20</em> ???????????<span>累计借贷金额(元)</span> ?????????</div> ?</div> ?</div><button id="saveImg">保存图片</button></body></html>
中间遇到问题:
结果:
样式有些缺失,官网明确指出不支持box-shadow等css样式
方案二:使用svg的forginObject属性将dom内容放入svg
链接:https://www.zhihu.com/question/20681535 中dion的回答
拷贝它的写法在我们的基础上修改,但是最后图片是svg形式。
<!DOCTYPE html><html><head><style>.main{ ?width: 900px; ?margin: 2rem auto; ?padding: 2rem 3rem; ?box-shadow: 0 0 23px rgba(221, 221, 221, 0.4);}h1{ ?text-align: center; ?font-size: 32px; ?color: #3e3e3e;}h1 span{ ?text-align: center; ?font-size: 16px; ?color: #ddd; ?display: block;}h2{ ?border-left: 5px solid #ff6a00; ?padding-left: 11px; ?font-size: 28px; ?font-weight: normal; ?line-height: 25px; ?margin-bottom: 50px; ?margin-top: 40px;}.box{ ?width: 20%; ?box-shadow: 0 0 22px rgba(221, 221, 221, 0.65); ?height: 6rem; ?padding: 1rem; ?font-size: 29px; ?text-align: center; ?margin-right: ?1%; ?display: inline-block; ?margin-bottom: 2%;}.box em{ ?font-weight: bold; ?font-style: normal; ?display: block; ?line-height: 1.5rem; ?margin-top: 1rem; ?font-size: 27px;}.box span{ ?font-size: 14px; ?color: #bdbdbd;}.clear{ ?clear: both; ?visibility: hidden;}</style></head><body><h2>Input Div:</h2><div id="input" style="width:900px"><div class=‘main‘ id="main"> ?<h1>蚂米平台实时运营数据 ???<span>数据统计截止时间:2018-05-27</span> ?</h1> ?<div> ???<h2>交易数据</h2> ???<h3>数据概览</h3> ???<div class=‘box‘> ?????<em>204571155.20</em> ?????<span>累计借贷金额(元)</span> ???</div> ???<div class=‘box‘> ?????<em>204571155.20</em> ?????<span>累计借贷金额(元)</span> ???</div> ???<div class=‘box‘> ?????<em>204571155.20</em> ?????<span>累计借贷金额(元)</span> ???</div> ???<div class=‘box‘> ?????<em>204571155.20</em> ?????<span>累计借贷金额(元)</span> ???</div> ???<div class=‘box‘> ???????<em>204571155.20</em> ???????<span>累计借贷金额(元)</span> ?????</div> ???????<div class=‘box‘> ???????<em>204571155.20</em> ???????<span>累计借贷金额(元)</span> ?????</div> ???????<div class=‘box‘> ???????<em>204571155.20</em> ???????<span>累计借贷金额(元)</span> ?????</div> ???????<div class=‘box‘> ???????<em>204571155.20</em> ???????<span>累计借贷金额(元)</span> ?????</div> ???????????<h3>数据概览</h3> ?????<div class=‘box‘> ???????<em>204571155.20</em> ???????<span>累计借贷金额(元)</span> ?????</div> ?????<div class=‘box‘> ???????<em>204571155.20</em> ???????<span>累计借贷金额(元)</span> ?????</div> ?????<div class=‘box‘> ???????<em>204571155.20</em> ???????<span>累计借贷金额(元)</span> ?????</div> ?????<div class=‘box‘> ???????<em>204571155.20</em> ???????<span>累计借贷金额(元)</span> ?????</div> ?????<div class=‘box‘> ???????<em>204571155.20</em> ???????<span>累计借贷金额(元)</span> ?????</div> ?????<h2>出借方和借款方信息</h2> ?????<div class=‘box‘> ?????????<em>204571155.20</em> ?????????<span>累计借贷金额(元)</span> ???????</div> ?????????<div class=‘box‘> ?????????<em>204571155.20</em> ?????????<span>累计借贷金额(元)</span> ???????</div> ?????????<div class=‘box‘> ?????????<em>204571155.20</em> ?????????<span>累计借贷金额(元)</span> ???????</div> ???????<div class=‘clear‘></div> ???????<div class=‘box‘> ???????????<em>204571155.20</em> ???????????<span>累计借贷金额(元)</span> ?????????</div> ?????????????<div class=‘box‘> ???????????<em>204571155.20</em> ???????????<span>累计借贷金额(元)</span> ?????????</div> ?????????????<div class=‘box‘> ???????????<em>204571155.20</em> ???????????<span>累计借贷金额(元)</span> ?????????</div> ???</div></div> ????</div><h2>Output Image:</h2><script>var divContent = document.getElementById(‘input‘).innerHTML;var data = "data:image/svg+xml," + "<svg xmlns=‘http://www.w3.org/2000/svg‘>" + "<foreignObject width=‘100%‘ height=‘100%‘>" + "<div xmlns=‘http://www.w3.org/1999/xhtml‘ style=‘font-size:16px;font-family:Helvetica‘>" + divContent + "</div>"+ "</foreignObject>" + "</svg>";var img = new Image();img.src = data;img.width = "1000";img.height = "2000";document.getElementsByTagName(‘body‘)[0].appendChild(img);</script><img id="outputImg" /></body></html>
中途遇到的问题:
svg对应image width和height没有正确设置,导致输出部分有时候展示不全
结果:
得到了svg,但是无法得到png
替代做法,使用svg代替png为图片资源,引用如下,t1.svg是从前面展示的out里面图片另存为得到的:
<html> ???<head></head> ???<body> ???????<img src="t1.svg" style="display:block;width:1000px;height:2000px"> ???</body></html>
方案三:dom->svg->canvas->png
参考链接:http://www.zhangxinxu.com/wordpress/2017/08/svg-foreignobject/
代码:
<html><head><style>.main{ ?width: 900px; ?margin: 2rem auto; ?padding: 2rem 3rem; ?box-shadow: 0 0 23px rgba(221, 221, 221, 0.4);}h1{ ?text-align: center; ?font-size: 32px; ?color: #3e3e3e;}h1 span{ ?text-align: center; ?font-size: 16px; ?color: #ddd; ?display: block;}h2{ ?border-left: 5px solid #ff6a00; ?padding-left: 11px; ?font-size: 28px; ?font-weight: normal; ?line-height: 25px; ?margin-bottom: 50px; ?margin-top: 40px;}.box{ ?width: 20%; ?box-shadow: 0 0 22px rgba(221, 221, 221, 0.65); ?height: 6rem; ?padding: 1rem; ?font-size: 29px; ?text-align: center; ?margin-right: ?1%; ?display: inline-block; ?margin-bottom: 2%;}.box em{ ?font-weight: bold; ?font-style: normal; ?display: block; ?line-height: 1.5rem; ?margin-top: 1rem; ?font-size: 27px;}.box span{ ?font-size: 14px; ?color: #bdbdbd;}.clear{ ?clear: both; ?visibility: hidden;}</style></head><body><div class=‘main‘ id="main"> ?<h1>蚂米平台实时运营数据 ???<span>数据统计截止时间:2018-05-27</span> ?</h1> ?<div> ???<h2>交易数据</h2> ???<h3>数据概览</h3> ???<div class=‘box‘> ?????<em>204571155.20</em> ?????<span>累计借贷金额(元)</span> ???</div> ???<div class=‘box‘> ?????<em>204571155.20</em> ?????<span>累计借贷金额(元)</span> ???</div> ???<div class=‘box‘> ?????<em>204571155.20</em> ?????<span>累计借贷金额(元)</span> ???</div> ???<div class=‘box‘> ?????<em>204571155.20</em> ?????<span>累计借贷金额(元)</span> ???</div> ???<div class=‘box‘> ???????<em>204571155.20</em> ???????<span>累计借贷金额(元)</span> ?????</div> ???????<div class=‘box‘> ???????<em>204571155.20</em> ???????<span>累计借贷金额(元)</span> ?????</div> ???????<div class=‘box‘> ???????<em>204571155.20</em> ???????<span>累计借贷金额(元)</span> ?????</div> ???????<div class=‘box‘> ???????<em>204571155.20</em> ???????<span>累计借贷金额(元)</span> ?????</div> ???????????<h3>数据概览</h3> ?????<div class=‘box‘> ???????<em>204571155.20</em> ???????<span>累计借贷金额(元)</span> ?????</div> ?????<div class=‘box‘> ???????<em>204571155.20</em> ???????<span>累计借贷金额(元)</span> ?????</div> ?????<div class=‘box‘> ???????<em>204571155.20</em> ???????<span>累计借贷金额(元)</span> ?????</div> ?????<div class=‘box‘> ???????<em>204571155.20</em> ???????<span>累计借贷金额(元)</span> ?????</div> ?????<div class=‘box‘> ???????<em>204571155.20</em> ???????<span>累计借贷金额(元)</span> ?????</div> ?????<h2>出借方和借款方信息</h2> ?????<div class=‘box‘> ?????????<em>204571155.20</em> ?????????<span>累计借贷金额(元)</span> ???????</div> ?????????<div class=‘box‘> ?????????<em>204571155.20</em> ?????????<span>累计借贷金额(元)</span> ???????</div> ?????????<div class=‘box‘> ?????????<em>204571155.20</em> ?????????<span>累计借贷金额(元)</span> ???????</div> ???????<div class=‘clear‘></div> ???????<div class=‘box‘> ???????????<em>204571155.20</em> ???????????<span>累计借贷金额(元)</span> ?????????</div> ?????????????<div class=‘box‘> ???????????<em>204571155.20</em> ???????????<span>累计借贷金额(元)</span> ?????????</div> ?????????????<div class=‘box‘> ???????????<em>204571155.20</em> ???????????<span>累计借贷金额(元)</span> ?????????</div> ???</div> ?<img/></div><button id="down">保存图片</button><script type="text/javascript">// DOM转图片的方法var domToImg = (function () { ???// 转png需要的canvas对象及其上下文 ???var canvas = document.createElement(‘canvas‘); ???var context = canvas.getContext(‘2d‘); ???????// canvas绘制图片元素方法 ???var draw = function (img) { ???????var width = img.width, height = img.height; ???????// canvas绘制 ???????canvas.width = width; ???????canvas.height = height; ???????// 画布清除 ???????context.clearRect(0, 0, width, height); ??????????//白色背景 ???????context.fillStyle = ‘#fff‘; ???????context.fillRect(0, 0, canvas.width, canvas.height); ???????????????// 绘制图片到canvas ???????context.drawImage(img, 0, 0); ???}; ???// canvas画布绘制的原图片 ???var img = new Image(); ???// 回调 ???var callback = function () {}; ???????// 图片回调 ???img.onload = function () { ???????draw(this); ???????// 回调方法 ???????callback(); ???}; ???????var exports = { ???????dom: null, ???????// DOM变成svg,并作为图片显示 ???????dom2Svg: function () { ???????????var dom = this.dom; ???????????if (!dom) { ???????????????return this; ???????????????} ???????????????????????// 复制DOM节点 ???????????var cloneDom = dom.cloneNode(true); ???????????cloneDom.setAttribute(‘xmlns‘, ‘http://www.w3.org/1999/xhtml‘); ???????????cloneDom.classList.remove(‘outline‘); ???????????????????????// 如果有图片,变成base64 ???????????var imgDom = null; ???????????if (cloneDom.tagName.toLowerCase() == ‘img‘) { ???????????????imgDom = cloneDom; ???????????} else { ???????????????// 这里就假设一个图片,多图自己遍历转换下就好了 ???????????????imgDom = cloneDom.querySelector(‘img‘); ???????????} ???????????????????????if (imgDom) { ???????????????draw(imgDom); ???????????????//imgDom.src = canvas.toDataURL(); ???????????????imgDom.src = canvas.toDataURL("image/png");; ???????????} ???????????????????????// 图片地址显示为DOM转换的svg ???????????img.src = ‘data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" width="‘ + dom.offsetWidth + ‘" height="‘ + dom.offsetHeight + ‘"><foreignObject x="0" y="0" width="100%" height="100%">‘+ ????????????????new XMLSerializer().serializeToString(cloneDom).replace(/#/g, ‘%23‘).replace(/\n/g, ‘%0A‘) + ???????????????document.querySelector(‘style‘).outerHTML + ????????????‘</foreignObject></svg>‘; ???????????????????????return this; ???????}, ???????// 作为图片下载,JS前端下载可参考这篇文章: ???????// JS前端创建html或json文件并浏览器导出下载 - http://www.zhangxinxu.com/wordpress/?p=6252 ???????download: function () { ???????????// 创建隐藏的可下载链接 ???????????var eleLink = document.createElement(‘a‘); ???????????// 下载图片文件名就按照时间戳来 ???????????eleLink.download = ‘zxx_png-‘ + (+new Date() + ‘‘).slice(1, 9) + ‘.png‘; ???????????eleLink.style.display = ‘none‘; ???????????????// 触发图片onload是个异步过程,因此,需要在回调中处理 ???????????callback = function () { ???????????????eleLink.href = canvas.toDataURL(); ???????????????// 触发点击 ???????????????document.body.appendChild(eleLink); ???????????????eleLink.click(); ???????????????// 然后移除 ???????????????document.body.removeChild(eleLink); ???????????????}; ???????????????????????// dom变图片 ???????????this.dom2Svg(); ???????} ???????}; ???????return exports;})();// 实例页面的交互代码var button = document.getElementById(‘down‘);// 点击并下载图片button.addEventListener(‘click‘, function (event) { ???var eleTarget = document.getElementById("main"); ???if (eleTarget !== this) { ???????domToImg.dom = eleTarget; ???????domToImg.download(); ???}});</script></html>
中途问题:
canvas转png时候得到的背景总是黑色的,听说转png时候是透明背景,jpeg是黑色背景,在toDataURL()中指定转换的类型
解决方案:
//白色背景 ???????context.fillStyle = ‘#fff‘; ???????context.fillRect(0, 0, canvas.width, canvas.height);
基本上就这样了。
实现html转png
原文地址:https://www.cnblogs.com/aigeileshei/p/9111925.html