一般页面都是.jsp页面,所以要把.jsp转换成html,在生成pdf,在网上找了好多方法,只有用一个插件,wkhtmltopdf-0.8.3.exe,生成的pdf会相对的好看。
先附上我做的.jsp页面。
<%@ page language="java" contentType="text/html;charset=utf-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <!DOCTYPE html> <html lang="en" id="htmlId"> <head> <meta charset="UTF-8" /> <style> .box{ /* 1000px; border:1px solid red; */ text-align: center; } table{ 100%; } table, th, td { border: 1px solid grey; border-collapse: collapse; font-size: 12px; } table th { height: 40px; line-height: 40px; background: #cdcdcd; text-align: center; } table td { height: 40px; line-height: 40px; color: black; text-align: center; } /*如果要隔行变色把下面解开换色就行*/ /* table tr:nth-child(odd) { background-color: white; } table tr:nth-child(even) { background-color:#99ccff; }*/ .civilRecord{ margin-top: 20px; } /*这是固定某一列表格的宽度*/ .civilRecord .th1{ 70px; } .civilRecord .th3{ 190px; } .civilRecord .th4{ 190px; } .civilRecord .th5{ 190px; } .protectionin{ margin-top: 20px; } .bj{ margin-left: 5%; margin-right: 5%; } </style> <script type="text/javascript" src="resource/jquery/jquery-1.9.1.min.js"></script> <script type="text/javascript"> function msg() { /* var url = 'assurehistory.do?reqCode=exportAssurehistoryPDF'; //window.location.href = url; var html=$("#htmlId").html(); //alert(html); //return; $.ajax({ type: "post", url: url, data: {htmlContent:html}, dataType: "json", success: function(data){ //alert(data.msg); } }); */ var form=$("<form>");//定义一个form表单 form.attr("style","display:none"); form.attr("target",""); form.attr("method","post"); form.attr("action","assurehistory.do?reqCode=exportAssurehistoryPDF"); var input1=$("<input>"); input1.attr("type","hidden"); input1.attr("name","htmlContent"); var html=$("#htmlId").html(); // alert(html); input1.attr("value",html); $("#pdfBody").append(form);//将表单放置在web中 form.append(input1); form.submit();//表单提交 } </script> </head> <body id="pdfBody"> <div class="box" style="height:430px;overflow:auto"> <div style="margin-left:80%;line-height: 28px;position: relative;"> <input type="button" value="导出PDF" onclick="msg()"/> </div> <!-- <h3>三 公共信息明细</h3> --> <div class="taxesRecord bj"> <p>个人担保基础信息</p> <table > <thead> <tr> <th>信息记录类型</th> <th>账户类型</th> <th>账户标识码</th> <th>信息报告日期</th> </tr> </thead> <tbody> <tr> <c:forEach var="assureinfos" items="${assureinfos}"> <td>${assureinfos.infotypetext}</td> <td>${assureinfos.acctypetext}</td> <td>${assureinfos.acccode}</td> <td>${assureinfos.repdateStr}</td> </c:forEach> </tr> </tbody> </table> <table> <thead> <tr> <th>报告时点说明代码</th> <th>债务人姓名</th> <th>债务人证件类型</th> <th>债务人证件号码</th> <th>业务管理机构代码</th> </tr> </thead> <tbody> <tr> <c:forEach var="assureinfos" items="${assureinfos}"> <td>${assureinfos.repcodetext}</td> <td>${assureinfos.debtorname}</td> <td>${assureinfos.debtoridtypetext}</td> <td>${assureinfos.debtoridnum}</td> <td>${assureinfos.organcode}</td> </c:forEach> </tr> </tbody> </table> </div> <div class="civilRecord bj"> <p>担保人基本信息</p> <table> <thead> <tr> <th class="th1">担保业务大类</th> <th class="th1">担保业务种类细分</th> <th class="th1">开户日期</th> <th class="th1">信用额度</th> <th class="th1">币种</th> </tr> </thead> <tbody> <tr> <c:forEach var="assurebasicinfos" items="${assurebasicinfos}"> <td>${assurebasicinfos.suretybusstext }</td> <td>${assurebasicinfos.suretybussspeartext}</td> <td>${assurebasicinfos.opendateStr }</td> <td>${assurebasicinfos.creditlimit }</td> <td>${assurebasicinfos.currencytypetext }</td> </c:forEach> </tr> </tbody> </table> <table> <thead> <tr> <th class="th1">到期日期</th> <th class="th1">反担保方式</th> <th class="th1">其他还款保证方式</th> <th class="th1">保证金百分比</th> <th class="th1">担保合同文本编号</th> </tr> </thead> <tbody> <tr> <c:forEach var="assurebasicinfos" items="${assurebasicinfos}"> <td>${assurebasicinfos.enddateStr }</td> <td>${assurebasicinfos.assuremodetext }</td> <td>${assurebasicinfos.otherasstext }</td> <td>${assurebasicinfos.marginpercent }</td> <td>${assurebasicinfos.assurenum }</td> </c:forEach> </tr> </tbody> </table> </div> <div class="civilRecord bj"> <p>在保责任信息</p> <table> <thead> <tr> <th class="th1">账户状态</th> <th class="th1">在保余额</th> <th class="th1">余额变化日期</th> <th class="th1">五级分类</th> <th class="th1">五级分类认定日期</th> </tr> </thead> <tbody> <tr> <c:forEach var="protectioninfos" items="${protectioninfos}"> <td>${protectioninfos.accstatetext }</td> <td>${protectioninfos.protectionbal }</td> <td>${protectioninfos.balchangedateStr }</td> <td>${protectioninfos.classifytext }</td> <td>${protectioninfos.classifydateStr }</td> </c:forEach> </tr> </tbody> </table> <table> <thead> <tr> <th class="th1">风险敞口</th> <th class="th1">代偿标志</th> <th class="th1">账户关闭日期</th> <th class="th1"></th> <th class="th1"></th> </tr> </thead> <tbody> <tr> <c:forEach var="protectioninfos" items="${protectioninfos}"> <td>${protectioninfos.riskexposure }</td> <td>${protectioninfos.compenflagtext }</td> <td>${protectioninfos.accclosedateStr }</td> <td></td> <td></td> </c:forEach> </tr> </tbody> </table> </div> <div class="civilRecord bj"> <p>相关还款人信息</p> <table> <thead> <tr> <th class="th1">责任人个数</th> <th class="th1">身份类别</th> <th class="th1">责任人名称</th> <th class="th1">责任人身份标识类型</th> <th class="th1">责任人身份标识号码</th> </tr> </thead> <c:forEach var="rep" items="${repaymentinfos}"> <tbody> <tr> <td>${rep.perliabnum}</td> <td>${rep.classifytypetext}</td> <td>${rep.perliabname}</td> <td>${rep.perliabtypetext}</td> <td>${rep.perliabid}</td> </tr> </tbody> </c:forEach> </table> <table> <thead> <tr> <th class="th1">还款责任人类型</th> <th class="th1">还款责任金额</th> <th class="th1"></th> <th class="th1"></th> <th class="th1"></th> </tr> </thead> <c:forEach var="rep" items="${repaymentinfos}"> <tbody> <tr> <td>${rep.reperliabtypetext}</td> <td>${rep.reperliabamot}</td> <td></td> <td></td> <td></td> </tr> </tbody> </c:forEach> </table> </div> <div class="civilRecord bj"> <p>抵押物信息</p> <table> <thead> <tr> <th class="th1">抵质押合同个数</th> <th class="th1">抵质押合同标识码</th> <th class="th1"></th> <th class="th1"></th> <th class="th1"></th> </tr> </thead> <c:forEach var="contractinfos" items="${contractinfos}"> <tbody> <tr> <td>${contractinfos.contractnum }</td> <td>${contractinfos.contractid }</td> <td></td> <td></td> <td></td> </tr> </tbody> </c:forEach> </table> </div> </div> </body> </html>
我用el表达式动态得到数据库里面的数据,然后在导出方法中,定义了from表单,把整个jsp源码获取到。
页面的效果:
下面附上后台的方法:
import java.io.BufferedInputStream;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.check.test.HtmlToPdf;
/** * 将html转成pdf * @param request * @param response * @return */ @RequestMapping(params = "reqCode=exportAssurehistoryPDF") public ModelAndView exportAssurehistoryPDF(HttpServletRequest request,HttpServletResponse response){ try { request.setCharacterEncoding("UTF-8"); } catch (UnsupportedEncodingException e2) { e2.printStackTrace(); } String h = request.getParameter("htmlContent"); System.out.println(h); String pPath=this.writeHtmlToFile(h, "assurehistory"); HtmlToPdf.convert(pPath+"/assurehistory.html", pPath+"/assurehistory.pdf"); try { //Thread.sleep(1000); response.setContentType("application/pdf"); response.addHeader("content-disposition", "attachment;filename="+ URLEncoder.encode("个人担保信息查询统计.pdf", "UTF-8")); File file = new File(pPath+"/assurehistory.pdf"); InputStream fis = new BufferedInputStream(new FileInputStream(file)); byte[] buffer = new byte[fis.available()]; fis.read(buffer); fis.close(); OutputStream os = response.getOutputStream(); os.write(buffer); os.flush(); os.close(); } catch (UnsupportedEncodingException e1) { e1.printStackTrace(); }catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; } /** * 将内容写入html文件 * @param content * @param htmlName * @return */ private String writeHtmlToFile(String content,String htmlName) { String path = ""; try { path = URLDecoder.decode(AssurehistoryController.class.getClassLoader().getResource("pdfFile/").getFile(), "utf-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } System.out.println(path); content=content.replace("<div class="box" style="height:430px;overflow:auto">", "<div class="box" style="overflow:auto">"); content=content.replace("button", "hidden").replace("HEIGHT: 430px", ""); File file = new File(path + htmlName+".html"); BufferedWriter bw = null; try { bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file),"utf-8")); bw.write("<!DOCTYPE html><html lang="en">"); bw.write(content); bw.write("</html>"); bw.flush(); } catch (IOException e) { e.printStackTrace(); } finally { if (bw != null) { try { bw.close(); } catch (IOException e) { e.printStackTrace(); } } } return file.getParent(); }
然后在定义一个HtmlToPdf类,你也可以把这个类的方法单独拿出来。
package com.check.test; import java.io.File; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; import com.eloan.app.assurehistory.controller.AssurehistoryController; public class HtmlToPdf { /** * html转pdf * @param srcPath html路径,可以是硬盘上的路径,也可以是网络路径 * @param destPath pdf保存路径 * @return 转换成功返回true */ public static boolean convert(String srcPath, String destPath){ //wkhtmltopdf在系统中的路径 String str=""; try { str = URLDecoder.decode(AssurehistoryController.class.getClassLoader().getResource("pdfFile/wkhtmltopdf-0.8.3.exe").getFile(), "utf-8"); } catch (UnsupportedEncodingException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } String path = new File(str).getPath(); File file = new File(destPath); File parent = file.getParentFile(); //如果pdf保存路径不存在,则创建路径 if(!parent.exists()){ parent.mkdirs(); } StringBuilder cmd = new StringBuilder(); cmd.append(path); cmd.append(" "); cmd.append(srcPath); cmd.append(" "); cmd.append(destPath); boolean result = true; try{ Process proc = Runtime.getRuntime().exec(cmd.toString()); proc.waitFor(); }catch(Exception e){ result = false; e.printStackTrace(); } return result; } }
最后,还有个重要的,就是wkhtmltopdf-0.8.3.exe,这个大家可以在网上免费下载,我把它放在我项目的src/main/java下面
最后,生成的pdf效果是: