html2canvas.js把html页面元素转成图片下载本地、上传服务器,处理图片模糊失真
1.引入js文件,html2canvas.js会有版本问题,这是我上传在git的版本,下载https://github.com/zhangliqingyun/jarlist/tree/master/html2canvas,头部引入文件
<script src="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"/>
<script th:src="@{/dist/js/html2canvas.js}"></script>
2.页面table元素:
<table id="table" style="width:100%;border-collapse:collapse;border:1px solid red;">
<tr style="border:1px solid red">
<td style="border:1px solid red ;width:70px;text-align:center;height:35px;line-height:35px;font-weight:bold;color:black">序号</td>
<td style="border:1px solid red ;text-align:center;height:35px;line-height:35px;font-weight:bold">文件名称</td>
<td style="border:1px solid red ;text-align:center;height:35px;line-height:35px;font-weight:bold">发布部门</td>
<td style="border:1px solid red ;text-align:center;height:35px;line-height:35px;font-weight:bold">发布时间</td>
</tr>
<tr style="border:1px solid red">
<td style="border:1px solid red ;text-align:center;height:35px;line-height:35px;font-weight:bold">1</td>
<td style="border:1px solid red ;text-align:center;height:35px;line-height:35px;font-weight:bold"><input name="fileName1" id="fileName1" class="mini-textbox" style="width:97%;margin:5px" onvaluechanged="valueChange()"/></td>
<td style="border:1px solid red ;text-align:center;height:35px;line-height:35px;font-weight:bold"><input name="partName1" class="mini-textbox" style="width:97%;margin:5px" onvaluechanged="valueChange()"/></td>
<td style="border:1px solid red ;text-align:center;height:35px;line-height:35px;font-weight:bold"><input name="releaseDate1" id="releaseDate1" class="mini-datepicker" onvaluechanged="valueChange()" format="yyyy-MM-dd" style="width:97%;margin:5px"/> </td>
</tr>
<tr style="border:1px solid red">
<td style="border:1px solid red ;text-align:center;height:35px;line-height:35px;font-weight:bold">2</td>
<td style="border:1px solid red ;text-align:center;height:35px;line-height:35px;font-weight:bold"><input name="fileName2" id="fileName2" class="mini-textbox" style="width:97%;margin:5px" onvaluechanged="valueChange()"/></td>
<td style="border:1px solid red ;text-align:center;height:35px;line-height:35px;font-weight:bold"><input name="partName2" class="mini-textbox" style="width:97%;margin:5px" onvaluechanged="valueChange()"/></td>
<td style="border:1px solid red ;text-align:center;height:35px;line-height:35px;font-weight:bold"><input name="releaseDate2" id="releaseDate2" class="mini-datepicker" onvaluechanged="valueChange()" format="yyyy-MM-dd" style="width:97%;margin:5px"/> </td>
</tr>
<tr style="border:1px solid red">
<td style="border:1px solid red ;text-align:center;height:35px;line-height:35px;font-weight:bold">3</td>
<td style="border:1px solid red ;text-align:center;height:35px;line-height:35px;font-weight:bold"><input name="fileName3" id="fileName3" class="mini-textbox" style="width:97%;margin:5px" onvaluechanged="valueChange()"/></td>
<td style="border:1px solid red ;text-align:center;height:35px;line-height:35px;font-weight:bold"><input name="partName3" class="mini-textbox" style="width:97%;margin:5px" onvaluechanged="valueChange()"/></td>
<td style="border:1px solid red ;text-align:center;height:35px;line-height:35px;font-weight:bold"><input name="releaseDate3" id="releaseDate3" class="mini-datepicker" onvaluechanged="valueChange()" format="yyyy-MM-dd" style="width:97%;margin:5px"/> </td>
</tr>
<tr style="border:1px solid red">
<td style="border:1px solid red ;text-align:center;height:35px;line-height:35px;font-weight:bold">4</td>
<td style="border:1px solid red ;text-align:center;height:35px;line-height:35px;font-weight:bold"><input name="fileName4" id="fileName4" class="mini-textbox" style="width:97%;margin:5px" onvaluechanged="valueChange()"/></td>
<td style="border:1px solid red ;text-align:center;height:35px;line-height:35px;font-weight:bold"><input name="partName4" class="mini-textbox" style="width:97%;margin:5px" onvaluechanged="valueChange()"/></td>
<td style="border:1px solid red ;text-align:center;height:35px;line-height:35px;font-weight:bold"><input name="releaseDate4" id="releaseDate4" class="mini-datepicker" onvaluechanged="valueChange()" format="yyyy-MM-dd" style="width:97%;margin:5px"/> </td>
</tr>
<tr style="border:1px solid red" >
<td style="border:1px solid red ;text-align:center;height:35px;line-height:35px;font-weight:bold">备注</td>
<td colspan="3" style="border:1px solid red ;text-align:center;height:45px;line-height:45px;font-weight:bold;"><textarea name="remark" class="mini-textarea" style="width:98%;margin:5px" onvaluechanged="valueChange()"></textarea></td>
</tr>
</table>
<a id="btn-Convert-Html2Image" href="#">下载</a>
3.js文件处理(下载到本地),模糊是由于scale的倍数设置必须为2的倍数
$(document).ready(function(){
$("#btn-Convert-Html2Image").on('click', function () {
var width = $('#table').outerWidth(); //截图元素的宽
var height = $('#table').outerHeight(); //截图元素的高
var canvas = document.createElement("canvas"); //创建画板
var context = canvas.getContext("2d");
var scale = 2; //设置为2的整数倍,2/4/6/8才出现不模糊的情况
canvas.width = width * scale;
canvas.height = height * scale;
canvas.getContext("2d").scale(scale, scale);
var opts = {
dpi: window.devicePixelRatio * 4,
scale: scale, // 添加的scale 参数
canvas: canvas, //自定义 canvas
width: width,
height: height,
useCORS: true // 【重要】开启跨域配置
};
html2canvas(document.querySelector("#table"), opts).then(canvas => {
var imgageData = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream"); // 获取生成的图片的url
$("#btn-Convert-Html2Image").attr("download", "your_pic_name.png").attr("href", imgageData);
});
});
});
4.页面截图
下载图片
5.上传到本地服务器,使用ajax把生成的图片base64字符串传递到后台保存
//上传table截图
function uploadPic(){
var width = $('#table').outerWidth(); //截图元素的宽
var height = $('#table').outerHeight(); //截图元素的高
var canvas = document.createElement("canvas"); //创建画板
var context = canvas.getContext("2d");
var scale = 2; //设置为2的整数倍,2/4/6/8才出现不模糊的情况
canvas.width = width * scale;
canvas.height = height * scale;
canvas.getContext("2d").scale(scale, scale);
var opts = {
dpi: window.devicePixelRatio * 4,
scale: scale, // 添加的scale 参数
canvas: canvas, //自定义 canvas
width: width,
height: height,
useCORS: true // 【重要】开启跨域配置
};
html2canvas(document.querySelector("#table"), opts).then(canvas => {
var imgageData = canvas.toDataURL("image/png").replace("data:image/png;base64,", "");
uploadPicByUrl(imgageData);//通过url上传图片
});
}
//通过url上传图片
function uploadPicByUrl(imgageData){
var orgCode = mini.get("orgCode").getValue();
$.ajax({
url: basePath+"gjHighItem111/savePic",
type: 'post',
data: {"data":imgageData,"picName":"H"+orgCode+"111.png"},
cache: false,
success: function (successData) {
var message = mini.decode(successData);
var msg = message.msg;//获取组织xxID,用于树节点定位
if(message.type == '200'){
showMsg("图片保存成功","success",800,"center","center");
}else{
showMsg("图片保存失败","warning",800,"center","center");
}
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
showMsg("图片保存错误","danger",800,"center","center");
}
});
}
6.后台接收代码
controller层:
@RequestMapping(value = "savePic", method = { RequestMethod.POST })
public String savePic(HttpServletRequest request){
String data = request.getParameter("data");
String picName = request.getParameter("picName");
return gjHighItem111Service.savePic(data,picName);
}
service层:PicUploadUtils.picPath为服务器路径,Base64字符串转成byte
public String savePic(String data, String picName) {
try {
byte[] bytes = new Base64().decodeBase64(data); //将字符串转换为byte数组
ByteArrayInputStream inputStreamArr = new ByteArrayInputStream(bytes); //要注意向后台传base64字符串时,要去掉 data:image/jpeg;base64, 前缀
InputStream inputStream = new BufferedInputStream(inputStreamArr); //把output流数组转成input流
File dir = new File(PicUploadUtils.picPath);
if (!dir.exists()) {
dir.mkdirs();
}
FileOutputStream fileOutputStream =new FileOutputStream(PicUploadUtils.picPath+picName);
//创建一个缓冲区
byte buffer[] = new byte[1024];
//判断输入流是否已经读完的标识
int len = 0;
while ((len=inputStream.read(buffer))>0)
{
fileOutputStream.write(buffer,0,len);
}
inputStream.close();
fileOutputStream.close();
} catch (Exception e) {
return new Message(Message.ERROR, "添加失败").toJson();
}
return new Message(Message.OK, "添加成功").toJson();
}