实现html转png
公司要求将一些重要数据全部以图片的形式放在官网上,防止网络爬虫。
之前都是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: 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: %;
box-shadow: 22px rgba(, , , 0.65);
height: 6rem;
padding: 1rem;
font-size: 29px;
text-align: center;
margin-right: %;
display: inline-block;
margin-bottom: %;
}
.box em{
font-weight: bold;
font-style: normal;
display: block;
line-height: .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")[]).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>数据统计截止时间:--</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: 23px rgba(, , , 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: %;
box-shadow: 22px rgba(, , , 0.65);
height: 6rem;
padding: 1rem;
font-size: 29px;
text-align: center;
margin-right: %;
display: inline-block;
margin-bottom: %;
}
.box em{
font-weight: bold;
font-style: normal;
display: block;
line-height: .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>数据统计截止时间:--</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 = "";
img.height = "";
document.getElementsByTagName('body')[].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: 23px rgba(, , , 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: %;
box-shadow: 22px rgba(, , , 0.65);
height: 6rem;
padding: 1rem;
font-size: 29px;
text-align: center;
margin-right: %;
display: inline-block;
margin-bottom: %;
}
.box em{
font-weight: bold;
font-style: normal;
display: block;
line-height: .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>数据统计截止时间:--</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(, , width, height);
//白色背景
context.fillStyle = '#fff';
context.fillRect(, , canvas.width, canvas.height);
// 绘制图片到canvas
context.drawImage(img, , );
}; // 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(, ) + '.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);
基本上就这样了。
随机推荐
- sgu 203 Hyperhuffman
题意:给出字符出现的次数,问替换成哈夫曼编码后的文本长度. 实际上观察发现就等于树的所有节点的和.用nlogn超时.用O(n),用两个队列,一个放原始数组,一个放新生成的节点. #include &l ...
- Android -------- MVC,MVP 和 MVVM 架构设计模式
MVC(Model-View-Controller)是最常见的软件架构之一,业界有着广泛应用.它本身很容易理解,但是要讲清楚,它与衍生的 MVP 和 MVVM 架构的区别就不容易了. 一.MVC MV ...
- win10+cpu+tensorflow+pycharm
1.安装64位的python3.5 选择windowsx86-64 executable installer安装 2.安装tensorflow cmd->进入到安装python的Scripts文 ...
- day11-15,装饰器
day11 1.装饰器 import time # print(time.time()) # 点数前边是从1970年到现在过了多少秒 # time.sleep(10) # 让程序执行到这里停一会儿 # ...
- 2015-2016 ACM-ICPC Northeastern European Regional Contest (NEERC 15)C - Cactus Jubilee
题意:给一颗仙人掌,要求移动一条边,不能放在原处,移动之后还是一颗仙人掌的方案数(仙人掌:无向图,每条边只在一个环中),等价于先删除一条边,然后加一条边 题解:对于一颗仙人掌,分成两种边,1:环边:环 ...
- python:extend (扩展) 与 append (追加) 之间的天与地
>>> li = ['a', 'b', 'c'] >>> li.extend(['d', 'e', 'f']) >>> li ['a', 'b', ...
- arguments.callee用法
arguments.callee 在哪一个函数中运行,它就代表哪一个函数. 一般用在匿名函数中. 在匿名函数中有时会需要自己调用自己,但是由于是匿名函数,没有名子,无名可调. 这时就可以用argume ...
- Leetcode 116
/** * Definition for binary tree with next pointer. * struct TreeLinkNode { * int val; * TreeLinkNod ...
- JedisClusterMaxRedirectionsException: Too many Cluster redirections
发生环境 当时的redis集群配置:redis-trib.rb 127.0.0.1 .... redis.conf的bind是默认# 解决方案 将redis.conf的bind为局域网真实ip red ...
- HttpClient4 警告: Invalid cookie header 的问题解决(转)
原文地址:HttpClient4 警告: Invalid cookie header 的问题解决 最近使用HttpClient4的时候出现如下警告信息 org.apache.http.client.p ...