最近公司要做个生成pdf电子账单凭证的功能,由于这个公司没有任何代码可借鉴,这个时候我就必须得自己搞明白具体的每一步应该怎么做,引什么jar包?用什么方式去实现?这篇博客中会给出从头到尾及其详细的代码和工具类以及jar包,方便大家需要时直接粘贴到自己项目中,此功能完成加调试1天即可完成,此案列可以用模板套打的方式完成合同以及账单或是单纯的文案式pdf。下面先给一张最终实现的效果图片。
在看到此图的时候我首先想到两种方案,第一个是直接由java生成pdf,每一行的生成都由java代码控制。第二种使用模板套打的方式,即我有个空白的pdf模板,把需要改变的地方的值置为空白,然后通过程序去写入。很明显第二种方案简单,且效率高。java实现对pdf的编辑用到了itext技术,引用了itext的相关jar包如下:
com.itextpdf
itextpdf
5.5.10
com.itextpdf
itext-asian
5.2.0
大家如果不是maven的项目可以去下载相应的jar包。
触发下载pdf的肯定是页面的某个按钮等,jsp页面代码如下:
function printPDF(outOrderId,serialNumber){//outOrderId,serialNumber 这是参数,可根据自己的项目需求来,window.open默认是get方式,所以参数大家需要注意一下
window.open(“${ctx}/pdf/print?templateName=certificate.pdf&outOrderId=”+outOrderId+”&serialNumber=”+serialNumber,’_blank’,
‘left=0,top=0,width=’+ (screen.availWidth – 10) +’,height=’+ (screen.availHeight-50) +’,scrollbars,resizable=yes,toolbar=yes’);
}
window.open方法中就不在此解释了,前面参数是访问后台的url,后面的是打开浏览器的一个新的页面和窗口。
紧跟着代码进入到后台的controller控制层,————————————————–
@RequestMapping(value = “/print”)
@ResponseBody
public void pdfPrint(@RequestParam(required=false,value=”templateName”) String templateName,
HttpServletRequest request, HttpServletResponse response,AgentPayDetailInfo agentForm) throws Exception {
//agentPayInfo 这个对象可以根据具体的需求换成你们自己的java对象,Text1-Text13,是pdf模板上空白处的表单的key值,通过该值可以用程序编辑pdf
//组装模板所需数据HashMap
HashMap mapPDF = new HashMap();
mapPDF.put(“Text1”, DateUtil.getDateFormatYH(agentPayInfo.getFinishDate()));//交易时间
mapPDF.put(“Text2”, Constants.PAY_ONESELF_NAME);//付款方全称
mapPDF.put(“Text3”, NumberToCN.number2CNMontrayUnit(agentPayInfo.getAmount()));//金额人民币大写 汉字
mapPDF.put(“Text4”, agentPayInfo.getCardholder());//账户名称
mapPDF.put(“Text5”, agentPayInfo.getBankCardNo());//银行卡号
mapPDF.put(“Text6”, agentPayInfo.getBankName());//开户行
mapPDF.put(“Text7”, agentPayInfo.getAmount().toString());金额人民币小写 数字
mapPDF.put(“Text8”, Constants.RMB);//账户类型
mapPDF.put(“Text9”, Constants.PAY_CERTIFICATE_TYPE);//交易类型
mapPDF.put(“Text10”, “”);//用途
mapPDF.put(“Text11”, Constants.PAY_CERTIFICATE_REMARK);//备注
String receiptNumber = DateUtil.getFDate(agentPayInfo.getFinishDate()) + agentPayInfo.getOutOrderId() + agentPayInfo.getSerialNumber();
mapPDF.put(“Text12”, “电子回单编号:” + receiptNumber);//电子回单编号
mapPDF.put(“Text13”, DateUtil.getFormatDate(agentPayInfo.getFinishDate()));//章子时间
//生成pdf
pdfStream = this.print(templateName, mapPDF, request);
ServletOutputStream op = response.getOutputStream();
response.setContentType(“application/pdf”);
response.setHeader(“Content-Disposition”, “inline; filename=\””
+ new String(receiptNumber.getBytes(“gb18030”), “ISO8859-1”) + “.pdf” + “\””);
int length = 0;
byte[] bytes = new byte[1024];
while ((pdfStream != null) && ((length = pdfStream.read(bytes)) != -1)) {
op.write(bytes, 0, length);
}
op.close();
response.flushBuffer();
}
/**
* 打印,以PDF为模板
* @param templateName String 模板名字
* @param map 模板数据HashMap
* @return InputStream
* @throws IOException
*/
private InputStream print(String templateName, HashMap map, HttpServletRequest request) throws IOException {
InputStream is = null;
//服务器端PDF模板文件名
//String merchId = getCurrentUser().getMerchId();
String realPath = request.getSession().getServletContext().getRealPath(“/”);
String web_info_URL = PropertyUtils.getValue(“WEB_INFO_URL”);
String agentPayPath = PropertyUtils.getValue(“PDF_PATH”);
String url = realPath + web_info_URL + agentPayPath;// pdf
String templatePath = url + “/model/”;//模板路径
String serverPath = url + “/template/”;//临时文件路径
PdfFormater pdf = new PdfFormater(templatePath, serverPath, templateName, map);
String PdfFilePath = pdf.doTransform();
is = new FileInputStream(PdfFilePath);
return is;
}
————————————————————————————————————————
输出给页面是用的ServletOutputStream,设置了response的.setContentType(“application/pdf”); 文件为pdf,,这种方式下载和打印方法