PDF电子合同
使用pdfescape生成一份PDF表单模板
1.打开网站 https://www.pdfescape.com/ 导入一份PDF模板文件
2.为PDF文件插入表单元素,并设置元素名称和各种属性
3.导出PDF表单模板,备用
使用itextpdf填入表单信息
1.创建一份java工程,引入itextpdf
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.11</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
2.设置表单数据和签名图片
package electronic;
import cn.hutool.core.date.DateUtil;
import com.itextpdf.text.Image;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.*;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.util.Date;
import java.util.HashMap;
/**
* @author hulu
* @description: 房屋租凭合同
* @date 2021/12/6 12:00
*/
public class HouseLeasingContract {
public static void main(String[] args) throws Exception {
// 模版文件
String templateFilePath = "C:\\Users\\Administrator\\Desktop\\HouseLeasingContract\\房屋租赁合同-模板_v2.2.pdf";
// 保存PDF文件
String fileCode = new Date().getTime()+"";
String pdfFilePath = "C:\\Users\\Administrator\\Desktop\\HouseLeasingContract\\房屋租赁合同_v2.2_"+fileCode+".pdf";
// 电子签名图片
String signImg = "C:\\Users\\Administrator\\Desktop\\HouseLeasingContract\\sign.png";
// 表单数据
HashMap<String,String> data = new HashMap<>();
data.put("owner_name","李zz");
data.put("owner_code","1102219575xxxxx9");
data.put("owner_mobile","157xxxx2555");
data.put("user_name","李uu");
data.put("user_code","1307231993xxxxxX");
data.put("user_mobile","135xxxx9713");
data.put("addr_detail","北京市昌平区xx村411号楼xxx号");
data.put("start_year","2021");
data.put("start_month","12");
data.put("start_day","06");
data.put("end_year","2022");
data.put("end_month","12");
data.put("end_day","05");
data.put("lease_months","12");
data.put("monthly_rent","1100");
data.put("prepay_num","10");
data.put("signing_date", DateUtil.formatDate(new Date()));
// 图片数据
HashMap<String,String> imageData = new HashMap<>();
imageData.put("sign",signImg);
// 根据PDF模版生成PDF文件
createPDF(templateFilePath,data,imageData,true,pdfFilePath);
}
/**
* 根据PDF模版生成PDF文件
* @param templateFilePath PDF模版文件路径
* @param data 表单数据
* @param imageData 图片数据 VALUE为图片文件路径
* @param formFlattening false:生成后的PDF文件表单域仍然可编辑 true:生成后的PDF文件表单域不可编辑
* @param pdfFilePath 生成PDF的文件路径
*/
private static void createPDF(String templateFilePath, HashMap<String,String> data, HashMap<String,String> imageData,
boolean formFlattening, String pdfFilePath) throws Exception{
PdfReader reader = null;
ByteArrayOutputStream bos = null;
PdfStamper pdfStamper = null;
FileOutputStream fos = null;
try{
// 读取PDF模版文件
reader = new PdfReader(templateFilePath);
// 输出流
bos = new ByteArrayOutputStream();
// 构建PDF对象
pdfStamper = new PdfStamper(reader, bos);
// 获取表单数据
AcroFields form = pdfStamper.getAcroFields();
// 使用中文字体 使用 AcroFields填充值的不需要在程序中设置字体,在模板文件中设置字体为中文字体 Adobe 宋体 std L
BaseFont bfChinese = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
form.addSubstitutionFont(bfChinese);
// 表单赋值
for(String key : data.keySet()){
form.setField(key,data.get(key));
// 也可以指定字体
form.setFieldProperty(key, "textfont", bfChinese, null);
}
// 添加图片
if(null != imageData && imageData.size() > 0){
for(String key : imageData.keySet()){
int pageNo = form.getFieldPositions(key).get(0).page;
Rectangle signRect = form.getFieldPositions(key).get(0).position;
float x = signRect.getLeft();
float y = signRect.getBottom();
// 读图片
Image image = Image.getInstance(imageData.get(key));
// 获取操作的页面
PdfContentByte under = pdfStamper.getOverContent(pageNo);
// 根据域的大小缩放图片
image.scaleToFit(signRect.getWidth(), signRect.getHeight());
// 添加图片
image.setAbsolutePosition(x, y);
under.addImage(image);
}
}
// 如果为false那么生成的PDF文件还能编辑,一定要设为true
pdfStamper.setFormFlattening(formFlattening);
pdfStamper.close();
// 保存文件
fos = new FileOutputStream(pdfFilePath);
fos.write(bos.toByteArray());
fos.flush();
}finally {
if(null != fos){
try {fos.close(); }catch (Exception e){e.printStackTrace();}
}
if(null != bos){
try {bos.close(); }catch (Exception e){e.printStackTrace();}
}
if(null != reader){
try {reader.close(); }catch (Exception e){e.printStackTrace();}
}
}
}
}
3.效果展示
合同模板
成品