前段时间有个电子签章的需求,需要将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只有图片,如果要文字编辑那么请采用报表形式生成