关于利用itext生成合同
1、 制作合同模板
1、 制作模板可以直接利用一款软件(Adobe Acrobat DC),可以在网上找免费破解版的,如果没有找到合适的版本,可以去我的百度云盘下载,地址:链接: http://pan.baidu.com/s/1c3qYj8 密码: xewr,软件安装这里就不说了。
2、 打开Adobe Acrobat DC,选择工具—准备表单
3、 选择文件—开始 ,然后进入模板制作界面。
4、 在需要填入内容处,填入对应的字段,如name,idCard…等,关于填字段的一些常用方法技巧,可参考附件2- Adobe Acrobat DC字段填入方法。模板制作完成后,就可以进入代码开发了。
2、 jar包准备
1、在这里,我选择itextpdf -5.5.10.jar和itext-asian-5.2.0.jar
需要注意下,如果用其他jar报错了,要改回我这个版本的,因为有的jar后期版本结构改变了,与asian结构不一致,会导致设置字体时候报错,建议使用以上两个版本jar。
3、 代码实现部分
1、控制层部分loanBaseController
@RequiresPermissions("loan:loanBase:edit")
@RequestMapping(value= "downloadContract")
publicvoid createContract (String loanBaseId,HttpServletRequest request,HttpServletResponseresponse){
Map
loanContractService.getData(dataMap,loanBaseId); // 对模板中填入的字段设置对应的value
//我这里是把模板放在maven项目的WeB_INF/pdf/common目录下,并且需要部署到linux上,因此路径的获取可能与其他存在差异,下面只是为了获取pdf模板的地址,便于后面生成输入流
StringrealPath = request.getSession().getServletContext().getRealPath("/");
StringpropertyPath =realPath+"WEB-INF"+File.separatorChar+"pdf"+File.separatorChar+"common";
StringfileName = “借款协议.pdf”;
StringtemplatePDF = propertyPath+File.separatorChar+fileName;
try{
InputStreamis = new FileInputStream(new File(templatePDF)); // pdf模板的输入流
ServletOutputStreamoutputStream = response.getOutputStream(); // 生成的新pdf输出流
response.setHeader("Content-Disposition","attachment;fileName=" + URLEncoder.encode(fileName,"UTF-8"));
loanContractService.doSomeThing(is,outputStream, dataMap); // 调用方法生成新的合同
}catch (Exception e1) {
e1.printStackTrace();
}
}
2、控制层部分LoanContractService
package com.***;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
importorg.springframework.stereotype.Service;
importorg.springframework.transaction.annotation.Transactional;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfCopy;
importcom.itextpdf.text.pdf.PdfImportedPage;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.kkyc.sass.common.utils.DateUtils;
importcom.kkyc.sass.common.utils.DoubleUtil;
importcom.kkyc.sass.common.utils.MoneyUtils;
importcom.kkyc.sass.common.utils.StringUtils;
importcom.kkyc.sass.modules.finance.entity.FinanceBase;
importcom.kkyc.sass.modules.finance.entity.FinanceReturn;
importcom.kkyc.sass.modules.finance.service.FinanceBaseService;
importcom.kkyc.sass.modules.finance.service.FinanceReturnService;
importcom.kkyc.sass.modules.loan.dao.LoanCarDao;
import com.kkyc.sass.modules.loan.entity.BaseCar;
importcom.kkyc.sass.modules.loan.entity.BaseUser;
importcom.kkyc.sass.modules.loan.entity.LoanBase;
importcom.kkyc.sass.modules.loan.entity.LoanCar;
importcom.kkyc.sass.modules.loan.entity.LoanProduct;
import com.kkyc.sass.modules.loan.entity.LoanProductAddition;
importcom.kkyc.sass.modules.loan.entity.LoanUser;
importcom.kkyc.sass.modules.sys.utils.DictUtils;
/**
* 合同操作Service
*@author wuyp
*@version 2017-03-07
*/
@Service
@Transactional(readOnly = true)
public class LoanContractService {
@Resource
privateBaseCarService baseCarService;
publicvoid getData(Map
LoanBaseloanBase = loanBaseService.get(loanBaseId);
//1.借款协议
dataMap.put("orderNum",loanBase.getOrderNum());
dataMap.put("userName",***);
dataMap.put("idCard",***);
dataMap.put("userNameB",***);
dataMap.put("idCardB",***);
…
}
/**
* 赋值并生成新的PDF文档
* @param is pdf模版输入流
* @param os 输出的新PDF流
* @param hashMap pdf模板对应的数据
* @author wuyp
*/
publicvoid doSomeThing(InputStream is,ServletOutputStream os,Map
try{
PdfReaderreader = new PdfReader(is); // 读取并解析pdf模板。
ByteArrayOutputStreambaos = new ByteArrayOutputStream(); // 创建一个新的字节数组输出流,缓冲容量为32字节,在必要时会增加
PdfStamperstamp = new PdfStamper(reader,baos); // 开始添加额外的过程内容到现有的PDF文档。
AcroFieldsform = stamp.getAcroFields(); // 获取允许设置值的AcroFields对象
form=setField(form,hashMap);
stamp.setFormFlattening(true);// 如果为false那么生成的PDF文件还能编辑,一定要设为true
stamp.close();
Documentdoc = new Document();
PdfCopypdfCopy = new PdfCopy(doc, os); // itext中合并页面的工具类
doc.open();
for(int i = 1; i <= reader.getNumberOfPages(); i++) {
PdfImportedPageimpPage = pdfCopy.getImportedPage(new PdfReader(baos.toByteArray()), i); // 从pdf模板中抓取第i个页面
pdfCopy.addPage(impPage);// 合并页面
}
doc.close();
os.flush();
}catch (FileNotFoundException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}catch (DocumentException e) {
e.printStackTrace();
}
}
/**
* 对模板中字段设置对应的value
* @Description (详细说明)
* @param form
* @param hashMap
* @return
* @Date 2017年3月29日 下午1:48:25
*/
@SuppressWarnings("unchecked")
publicstatic AcroFields setField(AcroFieldsform,Map
Set
Iterator
while(itr.hasNext()){
try{
Objecttemp = itr.next();
BaseFontbf =BaseFont.createFont("STSong-Light","UniGB-UCS2-H",BaseFont.NOT_EMBEDDED); // 创建字体
form.setFieldProperty(temp.toString(),"textfont", bf, null); // 设置字体
form.setFieldProperty(temp.toString(),"textsize", (float) 8, null); // 设置字体大小
/*BaseColorred = BaseColor.RED; // 设置字体颜色
form.setFieldProperty(temp.toString(),"textcolor", red, null);*/
form.setField(temp.toString(),(String)hashMap.get(temp.toString()));
} catch (IOException e) {
e.printStackTrace();
}catch (DocumentException e) {
e.printStackTrace();
}
}
returnform;
}
}
结束。。。
关于doSomeThing中的参数可以灵活配置,比如传入模板的路径,生成文件的路径,也是可以的,只需要能读取到pdf模板即可,例如pdfReader类中有很多构造方法可以读取解析文档,PdfReader pdfReader = new PdfReader(url);
附件下载地址:附件1-使用itext生pdf详解 http://download.csdn.net/detail/w20228396/9797795