实现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);
基本上就这样了。
随机推荐
- 【源码分析】Mybatis使用中,同一个事物里,select查询不出之前insert的数据
一.问题场景模拟问题:第二次查询和第一次查询结果一模一样,没有查询出我新插入的数据 猜测:第二次查询走了Mybatis缓存 疑问:那为什么会走缓存呢? 1.service方法 @Override @T ...
- linux文件管理之解压缩
文件的压缩与解压缩 Linux文件压缩工具有:gzip.bzip2.rar.7zip.lbzip2.xz.lrzip.PeaZip.arj等.============================= ...
- 2 爬虫 requests模块
requests模块 Requests是用python语言基于urllib编写的,采用的是Apache2 Licensed开源协议的HTTP库,Requests它会比urllib更加方便,reques ...
- 小程序用户openid设置放缓存
wx.setStorageSync('openid', res.data.data.openid),设置 var openid = wx.getStorageSync('openid')获取
- php数组的逐行写入文件与读取
<?php /** * * 对数组$arr1=['Apple Orange Banana Strawberry'] 写入文件,并读取 **/ class IoFile { private $pa ...
- 十分钟搞定pandas内容
目录 十分钟搞定pandas 一.创建对象 二.查看数据 三.选择器 十二.导入和保存数据 参考:http://pandas.pydata.org/pandas-docs/stable/whatsne ...
- Leetcode 692 - Note
1. 题目要求 Given a non-empty list of words, return the k most frequent elements. Your answer should be ...
- Codeforces Round #250 (Div. 1)E. The Child and Binary Tree
题意:有一个集合,求有多少形态不同的二叉树满足每个点的权值都属于这个集合并且总点权等于i 题解:先用生成函数搞出来\(f(x)=f(x)^2*c(x)+1\) 然后转化一下变成\(f(x)=\frac ...
- spring boot 多数据源配置与使用
在介绍使用JdbcTemplate和Spring-data-jpa时,都使用了单数据源.在单数据源的情况下,Spring Boot的配置非常简单,只需要在application.properties文 ...
- Pycharm中安装package出现microsoft visual c++ 14.0 is required问题解决办法
在利用pycharm安装scrapy包是遇到了挺多的问题.在折腾了差不多折腾了两个小时之后总算是安装好了.期间各种谷歌和百度,发现所有的教程都是利用命令行窗口安装的.发现安装scrapy需要的包真是多 ...