Java操作PDF文件實(shí)現(xiàn)簽訂電子合同詳細(xì)教程
前言:
前兩天領(lǐng)導(dǎo)提出需求要在pdf中加入電子簽章與電子簽名,然后自己查找了一些資料完成了,今天有時(shí)間正好分享一下,希望可以幫助到大家
先看效果:

1.編寫word文件
1.1先將模板編寫出來(可以根據(jù)自己的需求編寫)我這里是測(cè)試demo

1.2然后生成PDF格式進(jìn)行保存

1.3我這里是將文件保存到本地后上傳到華為云的OBS中,在本地也可以操作,我只是為了方便保存到數(shù)據(jù)庫(kù)中,可以根據(jù)自己的業(yè)務(wù)邏輯處理,效果雷同
注:這里上傳是在第二步完成后在操作


2.為PDF格式做表單
2.1然后將剛剛生成的pdf用PDF編輯器打開
注:我這里使用的是(萬興PDF)可以去找免費(fèi)的使用
打開后找到表單:

文字部分:
點(diǎn)擊文本字段,然后和截圖一樣吧自己需要添加文字的地方圈出來

然后在屬性中設(shè)置名稱(后面代碼操作會(huì)用到)

2.2圖片表單
然后在添加圖片表單,操作和文字一樣,吧需要放圖片的地方圈出來命名

這里需要注意的就是(外觀設(shè)置無顏色,不然后面生成出來會(huì)有邊框,特別丑)

然后在選項(xiàng)中選為僅標(biāo)簽(這樣公章就可以變的透明,可以根據(jù)自己的業(yè)務(wù)邏輯調(diào)整)

操作完成后保存
3.為表單賦值
public class PdfTest {
public static void main(String[] args) {
String fileName = "電子合同";
// 獲取當(dāng)前時(shí)間
Date currentDate = new Date();
// 創(chuàng)建一個(gè)SimpleDateFormat對(duì)象,指定日期格式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
// 格式化當(dāng)前時(shí)間
String formattedDate = sdf.format(currentDate);
//獲取當(dāng)前日期一年后的日期
String formattedDate2 = sdf.format(new Date(currentDate.getTime() + 365L * 24 * 60 * 60 * 1000));
System.err.println(formattedDate+"-"+formattedDate2);
//測(cè)試執(zhí)行
FillTemplate(
"剛剛添加表單保存的pdf文件的路徑",
"保存生成的pdf文件的路徑",
"XXX有限公司",
"張三豐",
"浙江寧波海曙區(qū)紅星大廈1706號(hào)",
"李四",
"18888888888",
"dawdawd@163.com",
formattedDate+"至"+formattedDate2,
formattedDate,
"簽名圖片的路徑",
"蓋章的路徑"
);
}
// 下面的參數(shù)就是表單中的名稱,需要對(duì)應(yīng)上不然找不到(需要注意大小寫)
public static void FillTemplate(
String sourcesPath,
String targetPath,
String name,
String fr,
String address,
String phoneName,
String phone,
String wx,
String data,
String newData,
String signPath,
String gongzhangPath
){
//設(shè)置參數(shù)
JSONObject jsonObject = new JSONObject();
jsonObject.put("name",name);
jsonObject.put("fr",fr);
jsonObject.put("address",address);
jsonObject.put("phoneName",phoneName);
jsonObject.put("phone",phone);
jsonObject.put("wx",wx);
jsonObject.put("data",data);
jsonObject.put("newData",newData);
// 填充創(chuàng)建pdf
PdfReader reader = null;
PdfStamper stamp = null;
ByteArrayOutputStream baos =null;
try {
reader = new PdfReader( sourcesPath);
File deskFile = new File(targetPath);
stamp = new PdfStamper(reader, new FileOutputStream(deskFile));
// 取出報(bào)表模板中的所有字段
AcroFields form = stamp.getAcroFields();
System.err.println(form.getFields().keySet());
//設(shè)置宋體
BaseFont song =BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
if (jsonObject != null) {
for (Map.Entry<String, Object> entry : jsonObject.entrySet()) {
String key = entry.getKey();
String value = entry.getValue().toString();
//保存選項(xiàng)
if (key.startsWith("select")) {
form.setField(key, value, true);
//保存文字
}else {
form.setFieldProperty(key, "textfont", song, null);
form.setField(key, value);
}
}
}
//插入簽名
insertImage(form,stamp,"sign",signPath);
//插入公章
insertImage(form,stamp,"gongzhang",gongzhangPath);
//保存修改
stamp.setFormFlattening(true);
}catch (Exception e){
e.printStackTrace();
}finally {
if (stamp != null) {
try{
stamp.close();
}catch (Exception e){
e.printStackTrace();
}
}
if (reader != null) {
try{
reader.close();
}catch (Exception e){
e.printStackTrace();
}
}
if (baos != null) {
try{
baos.close();
}catch (Exception e){
e.printStackTrace();
}
}
}
}
/**
* pdf模板插入圖片
* @param form
* @param stamper
* @param filedName
* @param url
* @return
*/
public static boolean insertImage(AcroFields form, PdfStamper stamper, String filedName, String url) {
try {
int pageNo = form.getFieldPositions(filedName).get(0).page;
Rectangle signRect = form.getFieldPositions(filedName).get(0).position;
float x = signRect.getLeft();
float y = signRect.getBottom();
Image image = Image.getInstance(url);
// 獲取操作的頁(yè)面
PdfContentByte under = stamper.getOverContent(pageNo);
// 根據(jù)域的大小縮放圖片
image.scaleToFit(signRect.getWidth(), signRect.getHeight());
// 添加圖片
image.setAbsolutePosition(x, y);
under.addImage(image);
}catch (Exception e){
return false;
}
return true;
}
}4.生成文檔
然后執(zhí)行后在保存生成的pdf文件的路徑中找到文件:

點(diǎn)擊查看:
效果圖:

5.上傳到OBS中
需要保存到數(shù)據(jù)庫(kù)中的上傳到OSS和OBS中都可以。。。
總結(jié)
到此這篇關(guān)于Java操作PDF文件實(shí)現(xiàn)簽訂電子合同的文章就介紹到這了,更多相關(guān)Java實(shí)現(xiàn)簽訂電子合同內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java利用DelayQueue實(shí)現(xiàn)延遲任務(wù)代碼實(shí)例
這篇文章主要介紹了Java利用DelayQueue實(shí)現(xiàn)延遲任務(wù)代碼實(shí)例,DelayQueue?是一個(gè)支持延時(shí)獲取元素的阻塞隊(duì)列,?內(nèi)部采用優(yōu)先隊(duì)列?PriorityQueue?存儲(chǔ)元素,同時(shí)元素必須實(shí)現(xiàn)?Delayed?接口,需要的朋友可以參考下2023-12-12
SpringBoot3.x中spring.factories?SPI?服務(wù)發(fā)現(xiàn)機(jī)制的改變問題小結(jié)
spring.factories其實(shí)是SpringBoot提供的SPI機(jī)制,底層實(shí)現(xiàn)是基于SpringFactoriesLoader檢索ClassLoader中所有jar引入的META-INF/spring.factories文件,這篇文章主要介紹了SpringBoot3.x中spring.factories?SPI?服務(wù)發(fā)現(xiàn)機(jī)制的改變,需要的朋友可以參考下2023-05-05
Idea中SpringBoot多模塊項(xiàng)目的建立實(shí)現(xiàn)
這篇文章主要介紹了Idea中SpringBoot多模塊項(xiàng)目的建立實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06
Java 實(shí)戰(zhàn)項(xiàng)目之疫情防控管理系統(tǒng)詳解
讀萬卷書不如行萬里路,只學(xué)書上的理論是遠(yuǎn)遠(yuǎn)不夠的,只有在實(shí)戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用Java實(shí)現(xiàn)一個(gè)疫情防控管理系統(tǒng),大家可以在過程中查缺補(bǔ)漏,提升水平2021-11-11
Java編程中使用throw關(guān)鍵字拋出異常的用法簡(jiǎn)介
這篇文章主要介紹了Java編程中使用throw關(guān)鍵字拋出異常的用法,是Java入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2015-11-11
java開發(fā)RocketMQ生產(chǎn)者高可用示例詳解
這篇文章主要為大家介紹了java開發(fā)RocketMQ生產(chǎn)者高可用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08
Java泛型實(shí)現(xiàn)類型安全的通用類型轉(zhuǎn)換器
在開發(fā)中,我們常常需要在不同類型之間進(jìn)行轉(zhuǎn)換,為了提高代碼的可讀性與安全性,Java的泛型機(jī)制提供了強(qiáng)大的類型檢查能力,下面我們就來看看如何通過泛型實(shí)現(xiàn)類型安全的通用轉(zhuǎn)換器2024-11-11
SpringBoot 數(shù)據(jù)存儲(chǔ)實(shí)戰(zhàn)指南
Elasticsearch是一個(gè)基于Apache Lucene開發(fā)的的搜索服務(wù),提供了一個(gè)分布式多用戶能力的全文搜索引擎,本文介紹如何在SpringBoot項(xiàng)目中整合ElasticSearch來完成數(shù)據(jù)的存儲(chǔ),感興趣的朋友跟隨小編一起看看吧2026-03-03
java開發(fā)Dubbo負(fù)載均衡與集群容錯(cuò)示例詳解
這篇文章主要為大家介紹了java開發(fā)Dubbo負(fù)載均衡與集群容錯(cuò)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步2021-11-11
java?io文件操作從文件讀取數(shù)據(jù)的六種方法
這篇文章主要為大家介紹了java?io操作總結(jié)從文件讀取數(shù)據(jù)的六種方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-03-03

