Java通过itext解析PDF中的关键字得到坐标进行插入印章图片或签名
需求
因需提高公司运转效率,提倡去无纸化操作,减少人力等前提;通过系统将审核通过后的pdf文档进行盖电子印章或电子签名等功能;
测试效果如下:
实现思路
因如上图1
中,存在动态表格,所以文档的布局是随数据而变的,可能是多页,可能是一页,且内容上下浮动,所以得通过解析文档内容,通过关键字
进行计算出关键字的坐标,再通过坐标进行实现电子印章图片的绝对定位;
代码实现
- 引入依赖
<!-- itext5 -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.9</version>
</dependency>
<!-- itext支持 -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itext-asian</artifactId>
<version>5.2.0</version>
</dependency>
- PdfUtils定位工具类
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.parser.PdfReaderContentParser;
import java.io.IOException;
/**
* Pdf定位工具类
*/
public class PdfUtils
{
/**
* @Author lcl
* @Date 11:24 2023/10/12
* @Description 用于供外部类调用获取关键字所在PDF文件坐标
* @param filepath 文件路径
* @param keyWords 关键词
* @return float[] 坐标
*/
public static float[] getKeyWordsByPath(String filepath, String keyWords)
{
float[] coordinate = null;
try
{
PdfReader pdfReader = new PdfReader(filepath);
coordinate = getKeyWords(pdfReader, keyWords);
} catch (IOException e)
{
e.printStackTrace();
}
return coordinate;
}
/**
* @Author lcl
* @Date 11:26 2023/10/12
* @Description 获取关键字所在PDF坐标
* @param pdfReader 流
* @param keyWords 关键词
* @return float[] 坐标
*/
public static float[] getKeyWords(PdfReader pdfReader, String keyWords)
{
float[] coordinate = null;
int page = 0;
try
{
int pageNum = pdfReader.getNumberOfPages();
PdfReaderContentParser pdfReaderContentParser = new PdfReaderContentParser(pdfReader);
CustomRenderListener renderListener = new CustomRenderListener();
renderListener.setKeyWord(keyWords);
for (page = 1; page <= pageNum; page++)
{
renderListener.setPage(page);
pdfReaderContentParser.processContent(page, renderListener);
coordinate = renderListener.getPcoordinate();
if (coordinate != null)
{
break;
}
}
}
catch (IOException e)
{
e.printStackTrace();
}
return coordinate;
}
}
- CustomRenderListener定位辅助类
import com.itextpdf.awt.geom.Rectangle2D.Float;
import com.itextpdf.text.pdf.parser.ImageRenderInfo;
import com.itextpdf.text.pdf.parser.RenderListener;
import com.itextpdf.text.pdf.parser.TextRenderInfo;
/**
* @Author lcl
* @Date 11:53 2023/10/12
* @Description pdf关键词帮助类
*/
public class CustomRenderListener implements RenderListener
{
private float[] pcoordinate = null;
private String keyWord;
private int page;
public int getPage()
{
return page;
}
public void setPage(int page)
{
this.page = page;
}
public float[] getPcoordinate()
{
return pcoordinate;
}
public String getKeyWord()
{
return keyWord;
}
public void setKeyWord(String keyWord)
{
this.keyWord = keyWord;
}
@Override
public void beginTextBlock() {}
@Override
public void endTextBlock() {}
@Override
public void renderImage(ImageRenderInfo arg0) {}
@Override
public void renderText(TextRenderInfo textRenderInfo)
{
String text = textRenderInfo.getText();
if (null != text && text.contains(keyWord)) {
Float boundingRectange = textRenderInfo.getBaseline().getBoundingRectange();
pcoordinate = new float[3];
pcoordinate[0] = boundingRectange.x;
pcoordinate[1] = boundingRectange.y;
pcoordinate[2] = page;
}
}
}
- 测试
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfGState;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import java.io.*;
public class TestUtils
{
public static void main(String[] args) throws IOException, DocumentException
{
// 原文件
File file = new File("C:\\Users\\Administrator\\Desktop\\JYX_QYZT\\test1.pdf");
// 处理后的文件
FileOutputStream outputStream = new
FileOutputStream("C:\\Users\\Administrator\\Desktop\\JYX_QYZT\\test2.pdf");
// 读
PdfReader reader = new PdfReader(new FileInputStream(file));
// 获取关键词坐标
float[] xyz = PdfUtils.getKeyWords(reader,"审核:");
if (xyz == null)
{
return;
}
System.out.println("x:"+ xyz[0]);
System.out.println("y:"+ xyz[1]);
System.out.println("页码:"+ xyz[2]);
PdfStamper stamper = new PdfStamper(reader, outputStream);
// 将印章图片放在pdf文件的第?页
PdfContentByte over = stamper.getOverContent((int) xyz[2]);
// 需要插入的图片
Image contractSealImg = Image.getInstance("http://192.168.8.116:9000/erp/bpm/scms/印章.png");
// 保存状态
over.saveState();
// 图片处理
PdfGState pdfGState = new PdfGState();
// 给图片设置透明度,一般不需要
pdfGState.setFillOpacity(0.8F);
over.setGState(pdfGState);
// 设置图片位置
contractSealImg.setAbsolutePosition(xyz[0], xyz[1]);
// 设置图片大小
contractSealImg.scaleAbsolute(100, 100);
// 将图片添加到pdf文件
over.addImage(contractSealImg);
over.restoreState();
stamper.setFormFlattening(true);
// 关闭流
stamper.close();
reader.close();
outputStream.close();
}
}
bug怎么这么多!