一、POM引用依赖
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.6</version>
</dependency>
<!-- itextpdf的亚洲字体支持 -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
二、上代码
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Image;
import com.itextpdf.text.pdf.*;
import com.itextpdf.text.pdf.parser.ImageRenderInfo;
import com.itextpdf.text.pdf.parser.PdfReaderContentParser;
import com.itextpdf.text.pdf.parser.RenderListener;
import com.itextpdf.text.pdf.parser.TextRenderInfo;
import org.apache.commons.lang3.StringUtils;
import java.io.*;
import java.time.LocalDateTime;
import java.util.*;
public class PdfSignUtil {
private static int imageWith = 120;
private static int imageHight = 60;
public static String sealSign(String pdfBase64) throws IOException, DocumentException {
String sealTime = "&D0";
InputStream input = FileUtils.baseToInputStream(pdfBase64.getBytes());
PdfReader reader = new PdfReader(input);
Map<Integer, List<KeyWordBean>> map = getPDFText(pdfBase64);
File temp = File.createTempFile(System.currentTimeMillis()+new Random(100).nextInt()+"", ".pdf");
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(temp));
signTime(stamper,map,sealTime);
stamper.close();
reader.close();
return Base64.createBase64().encode(FileUtils.readFileTobytes(temp));
}
public static String sign(String pdfBase64, String imagePath,int index,String signWord,String signWordTime, String signIdea, String authIdea) throws IOException, DocumentException {
InputStream input = FileUtils.baseToInputStream(pdfBase64.getBytes());
PdfReader reader = new PdfReader(input);
Map<Integer, List<KeyWordBean>> map = getPDFText(pdfBase64);
List<KeyWordBean> beanlist = getKeyWordXYLast(map, signWord);
if(beanlist.isEmpty()){
return null;
}
File temp = File.createTempFile(System.currentTimeMillis()+new Random(100).nextInt()+"", ".pdf");
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(temp));
AcroFields form = stamper.getAcroFields();
form.addSubstitutionFont(BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", false));
KeyWordBean keyWordBean = beanlist.get(0);
int pageNo = keyWordBean.getPage();
float x = keyWordBean.getX();
float y = keyWordBean.getY();
Image image = Image.getInstance(imagePath);
PdfContentByte under = stamper.getOverContent(pageNo);
image.scaleAbsolute(keyWordBean.getWidth(), keyWordBean.getWidth() * imageHight / imageWith );
image.setAbsolutePosition(x, y);
image.setInterpolation(true);
under.addImage(image);
if(StringUtils.isNotBlank(signWordTime)){
signTime(stamper,map,signWordTime);
}
if(StringUtils.isNotBlank(signIdea)){
signIdea(stamper,map,signIdea,authIdea);
}
stamper.close();
reader.close();
return Base64.createBase64().encode(FileUtils.readFileTobytes(temp));
}
public static void signTime(PdfStamper stamper, Map<Integer, List<KeyWordBean>> map,String signWordTime) throws IOException, DocumentException {
List<KeyWordBean> beanlist = getKeyWordXYLast(map, signWordTime);
if(beanlist.isEmpty()){
return;
}
for (KeyWordBean keyWordBean : beanlist) {
int pageNo = keyWordBean.getPage();
float x = keyWordBean.getX();
float y = keyWordBean.getY();
PdfContentByte overContent = stamper.getOverContent(pageNo);
BaseFont font = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", false);
overContent.beginText();
overContent.setFontAndSize(font, 10);
overContent.setTextMatrix(200, 200);
overContent.showTextAligned(Element.ALIGN_CENTER,DateUtils.formatDate(LocalDateTime.now(),"yyyy年MM月dd日"),x+34,y,0);
overContent.endText();
}
}
public static void signIdea(PdfStamper stamper, Map<Integer, List<KeyWordBean>> map,String signIdea, String authIdea) throws IOException, DocumentException {
List<KeyWordBean> beanlist = getKeyWordXYLast(map, signIdea);
authIdea = StringUtils.isBlank(authIdea) ? "" : authIdea;
if(beanlist.isEmpty()){
return;
}
KeyWordBean keyWordBean = beanlist.get(0);
int pageNo = keyWordBean.getPage();
float x = keyWordBean.getX();
float y = keyWordBean.getY();
PdfContentByte overContent = stamper.getOverContent(pageNo);
BaseFont font = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", false);
overContent.beginText();
overContent.setFontAndSize(font, 10);
overContent.setTextMatrix(200, 100);
overContent.showTextAligned(Element.ALIGN_CENTER,authIdea,x+34,y,0);
overContent.endText();
return;
}
public static Map<Integer, List<KeyWordBean>> getPDFText(String filePath) {
Map<Integer, List<KeyWordBean>> map = new HashMap<Integer, List<KeyWordBean>>();
try {
PdfReader pdfReader = new PdfReader(FileUtils.baseToInputStream(filePath.getBytes()));
int pageNum = pdfReader.getNumberOfPages();
PdfReaderContentParser pdfReaderContentParser = new PdfReaderContentParser(pdfReader);
for (int i = 1; i <= pageNum; i++) {
List<KeyWordBean> lists = Lists.newArrayList();
List<Integer> pagelist = new ArrayList<Integer>();
pagelist.add(0, i);
pdfReaderContentParser.processContent(i, new RenderListener() {
@Override
public void renderText(TextRenderInfo textRenderInfo) {
String text = textRenderInfo.getText();
com.itextpdf.awt.geom.Rectangle2D.Float boundingRectange = textRenderInfo.getBaseline()
.getBoundingRectange();
KeyWordBean bean = new KeyWordBean();
bean.setX(boundingRectange.x);
bean.setY(boundingRectange.y);
bean.setWidth(boundingRectange.width);
bean.setPage(pagelist.get(0));
bean.setText(text);
lists.add(bean);
}
@Override
public void renderImage(ImageRenderInfo arg0) {
}
@Override
public void endTextBlock() {
}
@Override
public void beginTextBlock() {
}
});
map.put(i, lists);
}
} catch (IOException e) {
e.printStackTrace();
}
return map;
}
private static KeyWordBean getKeyWordXY(Map<Integer, List<KeyWordBean>> map2, int page, int num, String keyWord) {
List<KeyWordBean> list=getKeyWordXY(map2,keyWord);
for(KeyWordBean bean:list) {
if(bean.getPage()==page && bean.getNum()==num) {
return bean;
}
}
return null;
}
public static List<KeyWordBean> getKeyWordXYLast(Map<Integer, List<KeyWordBean>> map2,String keyWord) {
int keyMatch = 1;
StringBuilder content = new StringBuilder();
List<KeyWordBean> keywordlist= new ArrayList<KeyWordBean>();
for(int page:map2.keySet()) {
List<KeyWordBean> list=map2.get(page);
Collections.sort(list);
for (int i = 0; i < list.size(); i++) {
KeyWordBean bean = list.get(i);
String text = bean.getText();
if (i + 1 != list.size()) {
KeyWordBean beanNext = list.get(i + 1);
float x = beanNext.getX() - bean.getX();
float y = beanNext.getY() - bean.getY();
if (y == 0 && x <= 1) {
} else {
if (StringUtils.contains(content.toString(), keyWord) || StringUtils.contains(text, keyWord)) {
bean.setNum(keyMatch++);
keywordlist.add(bean);
} else if ((!StringUtils.isEmpty(text) && keyWord.startsWith(text)) || content.length() > 0) {
content.append(text);
if (content.length() >= keyWord.length()) {
if (StringUtils.contains(content.toString(), keyWord)) {
bean.setNum(keyMatch++);
keywordlist.add(bean);
}
content = new StringBuilder();
}
}
}
} else {
if (StringUtils.contains(content.toString(), keyWord) || StringUtils.contains(text, keyWord)) {
bean.setNum(keyMatch++);
keywordlist.add(bean);
} else if ((!StringUtils.isEmpty(text) && keyWord.startsWith(text)) || content.length() > 0) {
content.append(text);
if (content.length() >= keyWord.length()) {
if (StringUtils.contains(content.toString(), keyWord)) {
bean.setNum(keyMatch++);
keywordlist.add(bean);
}
content = new StringBuilder();
}
}
}
}
}
return keywordlist;
}
public static List<KeyWordBean> getKeyWordXY(Map<Integer, List<KeyWordBean>> map2,String keyWord) {
int keyMatch = 1;
StringBuilder content = new StringBuilder();
List<KeyWordBean> keywordlist= new ArrayList<KeyWordBean>();
for(int page:map2.keySet()) {
List<KeyWordBean> list=map2.get(page);
Collections.sort(list);
for (int i = list.size() - 1; i > 0; i --) {
KeyWordBean bean = list.get(i);
String text = bean.getText();
if (i - 1 >= 0) {
KeyWordBean beanNext = list.get(i - 1);
float x = bean.getX() - beanNext.getX();
float y = bean.getY() - beanNext.getY();
if (y == 0 && x <= 1) {
} else {
if (StringUtils.contains(content.toString(), keyWord) || StringUtils.contains(text, keyWord)) {
bean.setNum(keyMatch++);
keywordlist.add(bean);
} else if ((!StringUtils.isEmpty(text) && keyWord.endsWith(text)) || content.length() > 0) {
content.insert(0,text);
if (content.length() >= keyWord.length()) {
if (StringUtils.contains(content.toString(), keyWord)) {
bean.setNum(keyMatch++);
keywordlist.add(bean);
}
content = new StringBuilder();
}
}
}
} else {
if (StringUtils.contains(content.toString(), keyWord) || StringUtils.contains(text, keyWord)) {
bean.setNum(keyMatch++);
keywordlist.add(bean);
} else if ((!StringUtils.isEmpty(text) && keyWord.startsWith(text)) || content.length() > 0) {
content.append(text);
if (content.length() >= keyWord.length()) {
if (StringUtils.contains(content.toString(), keyWord)) {
bean.setNum(keyMatch++);
keywordlist.add(bean);
}
content = new StringBuilder();
}
}
}
}
}
return keywordlist;
}
public static void main(String[] args) {
try {
sign(Base64.createBase64().encode(FileUtils.readFileTobytes("C:\\Users\\xxx\\Desktop\\test02.pdf")),
"C:\\Users\\xxx\\Desktop\\166.png",0,"关键字#1",null,null,null);
} catch (IOException e) {
e.printStackTrace();
} catch (DocumentException e) {
e.printStackTrace();
}
}
}