前段时间有个电子签章的需求,需要将jsp页面内容生成pdf文件,然后传给电子签章。自己尝试过集中方法,有的集成麻烦,需要引入报表。再就是速度慢,流程很长,不适用于高并发。这里整理了一个了很简单灵活的方法,而且很方便理解。
代码思路:
jsp页面通过html2canvas.js来截取div转成image图片,然后将图片提交到服务端,服务端创建pdf文件将图片插进去。
资源依赖:html2canvas.js (截取图片) itextpdf-5.5.9.jar(生成pdf文件)
前端源码:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<title>Test</title>
<style type="text/css">
*{
margin:0 auto;
padding:0;
}
.btn{
width:100px;
height:30px;
line-height:30px;
background:green;
color:#fff;
border-radius:10px;
-webkit-border-radius:10px;
text-align:center;
display:block;
text-decoration:none;
}
.container{
background:#e5e5e5;
}
</style>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="https://cdn.bootcss.com/html2canvas/0.4.1/html2canvas.js"></script>
<script>
$(function(){
$("#btn").click(function(){
html2canvas($("#container"), {
onrendered: function(canvas) {
//把截取到的图片替换到a标签的路径下载
//$("#download").attr('href',canvas.toDataURL());
alert(canvas.toDataURL());
$.post("<%=request.getContextPath()%>/test",{image:canvas.toDataURL()},function(result){
alert("成功");
});
//下载下来的图片名字
//$("#download").attr('download','share.png') ;
//document.body.appendChild(canvas);
},
useCORS: true //解决资源跨域问题
//可以带上宽高截取你所需要的部分内容
// ,
// width: 300,
// height: 300
});
});
});
</script>
</head>
<body>
<div style="padding:10px 0">
<div class="btn" id="btn">截取屏幕</div>
<p style="color:red; text-align:center;">先点击截取屏幕后再点击截图下载</p>
<div style="margin-top:10px">
<a href="javascript:;" rel="external nofollow" class="btn" id="download">截图下载</a>
</div>
</div>
<div class="container" id="container">
<p style="text-align:center">以下是测试内容</p>
<img src="http://a.hiphotos.baidu.com/image/pic/item/9f510fb30f2442a76160eca6dd43ad4bd1130242.jpg">
</div>
</body>
</html>
服务端源码:
public void createPDF(HttpServletRequest request, HttpServletResponse response) throws DocumentException, MalformedURLException, IOException{
String imgStr=request.getParameter("image");
byte[] b=GenerateImage(imgStr.replace("data:image/png;base64,", ""));
// 1.新建document对象
Document document = new Document();
// 2.建立一个书写器(Writer)与document对象关联,通过书写器(Writer)可以将文档写入到磁盘中。
// 创建 PdfWriter 对象 第一个参数是对文档对象的引用,第二个参数是文件的实际名称,在该名称中还会给出其输出路径。
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("D:/chenggong.pdf"));
// 3.打开文档
document.open();
// 4.添加一个内容段落
//document.add(new Paragraph("Hello World!"));
//图片1
Image image1 = Image.getInstance(b);
//设置图片位置的x轴和y周
image1.setAbsolutePosition(100f, 550f);
//设置图片的宽度和高度
image1.scaleAbsolute(200, 200);
//将图片1添加到pdf文件中
document.add(image1);
// 5.关闭文档
document.close();
}
/**
* base64字符串转化成图片
* @param imgStr
* @return
* @throws IOException
*/
public byte[] GenerateImage(String imgStr) throws IOException { // 对字节数组字符串进行Base64解码并生成图片
// if (imgStr == null) // 图像数据为空
BASE64Decoder decoder = new BASE64Decoder();
// Base64解码
byte[] b = decoder.decodeBuffer(imgStr);
for (int i = 0; i < b.length; ++i) {
if (b[i] < 0) {// 调整异常数据
b[i] += 256;
}
}
// 生成jpeg图片
// String imgFilePath = "E:/test33.jpg";// 新生成的图片
// OutputStream out = new FileOutputStream(imgFilePath);
// out.write(b);
// out.flush();
// out.close();
return b;
}
这只是个简单的demo,具体尺寸参数根据需求配置
注意:html2canvas截取部分,如果数据是以特有的标签赋值请修改赋值方式,比如C标签的循环方式赋值,这时候可能截取的页面会乱,这个方法生成的pdf只有图片,如果要文字编辑那么请采用报表形式生成