利用itextpdf实现简单的电子签章只需要itextpdf相关jar包,构建一个简单的javademo就可以模拟。在web项目上大同小异,只需要得到对应的文件即可以作为工具进行调用
准备:itextpdf-5.5.13.jar,itextpdf-5.5.8.jar都可以。
准备待签名文件(路径)、签章,矢量即可(直接上代码)
代码如下:
//电子签章(传入源文件,输出文件、签章图片)
public static void addMark(String inSource,String outSource,String sealPNG){
try {
//读取需要签章的文档信息
Map
//获取文件宽度,默认pdf
float startAddress = Float.valueOf(SealUtils.getString(pdfMsg.get("width")));
PdfReader reader = new PdfReader(new FileInputStream(inSource));
PdfStamper stamper =new PdfStamper(reader, new FileOutputStream(outSource));
//利用关键字查找文件中的内容,确定签章的位置
List
keyWordsList.add("敏感字");
//查找关键字位置
List> arrLists = SealUtils.findKeywords(keyWordsList,reader);
int pageNum = SealUtils.getInt(pdfMsg.get("pageSize"));
//插入水印
Image img = Image.getInstance(sealPNG);
//设置尺寸
img.scaleAbsolute(90,60);// 直接设定显示尺寸
img.setBackgroundColor(new BaseColor(0));
//如果没有找到关键字,走默认位置
if(arrLists.isEmpty()){
//默认盖章位置
img.setAbsolutePosition(startAddress - 188,70);
PdfContentByte overContent = stamper.getOverContent(pageNum);
overContent.addImage(img);
stamper.close();
reader.close();
return;
}
for (int i=pageNum;i>0;i--) {
if(!arrLists.get(0).isEmpty()){
// 关键字所在的页码数
float pageFlag = arrLists.get(0).get(0)[2];
// 当且仅当落款和关键字在同一页时考虑同时盖章
if (pageNum == pageFlag && pageFlag == i) {
img.setAbsolutePosition(arrLists.get(0).get(0)[0] - 60,
arrLists.get(0).get(0)[1] - 60);
}
PdfContentByte under = stamper.getOverContent(i);
under.addImage(img);
//添加文字水印
doTextHide(under);
//图片水印
doImgHide(under,sealPNG);
}
}
stamper.close();
reader.close();
} catch (FileNotFoundException e) {
logger.info("传入文件有问题!。。"+e.getMessage());
} catch (IOException e) {
logger.info("文件传输错误!。。"+e.getMessage());
} catch (DocumentException e) {
logger.info("解析pdf文档有问题!。。"+e.getMessage());
}
}
工具方法抽取
/**
* 添加文字水印
* @throws IOException
* @throws DocumentException
*/
public static void doTextHide(PdfContentByte under) throws DocumentException, IOException{
logger.info("添加文字水印!");
PdfGState gState = new PdfGState();
under.beginText();
BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA_BOLDOBLIQUE,BaseFont.WINANSI,BaseFont.NOT_CACHED);
under.setFontAndSize(bf, 45);
under.setTextMatrix(30, 30);
under.setColorFill(BaseColor.PINK);
gState.setFillOpacity(0.3f);
under.setGState(gState);
under.showTextAligned(Element.ALIGN_LEFT, "JASON_HSUEH", 230, 430, 45);
under.endText();
}
/**
* 添加图片水印
* @throws IOException
* @throws MalformedURLException
* @throws DocumentException
*/
public static void doImgHide(PdfContentByte under,String path) throws MalformedURLException, IOException, DocumentException{
under.beginText();
PdfGState gState = new PdfGState();
gState.setStrokeOpacity(0.4f);
Image image = Image.getInstance(path);
// 设置坐标 绝对位置 X Y
image.setAbsolutePosition(200, 300);
// 设置旋转弧度
image.setRotation(30);// 旋转 弧度
// 设置旋转角度
image.setRotationDegrees(45);// 旋转 角度
// 设置等比缩放
image.scalePercent(90);// 依照比例缩放
// image.scaleAbsolute(200,100);//自定义大小
// 设置透明度
under.addImage(image);
under.setGState(gState);
under.endText();
under.stroke();
}
其中:SealUtils.findKeywords(keyWordsList,reader)实现在对应文件中搜索关键字
/**
* 根据关键字返回对应的坐标
* @param keyWords
* @param pdfReader
* @return
*/
public static List> findKeywords(final List
if (keyWords.isEmpty()) {
return null;
}
int pageNum = pdfReader.getNumberOfPages();
final List> arrayLists = new ArrayList
>(keyWords.size());
for (int k=0; k
arrayLists.add(positions);
}
PdfReaderContentParser pdfReaderContentParser = new PdfReaderContentParser(pdfReader);
try {
for (int i = 1; i <= pageNum; i++) {
final int finalI = i;
pdfReaderContentParser.processContent(i, new RenderListener() {
public String pdfsb=new String();
private float yy = -1f;
@Override
public void renderText(TextRenderInfo textRenderInfo) {
String text = textRenderInfo.getText();
com.itextpdf.awt.geom.Rectangle2D.Float boundingRectange = textRenderInfo.getBaseline().getBoundingRectange();
if(yy == -1f) {
yy = boundingRectange.y;
}
if(yy != boundingRectange.y) {
yy = boundingRectange.y;
}
pdfsb +=text;
if (pdfsb.length()>0) {
for (int j=0; j
//假如配置了多个关键字,找到一个就跑
for (final String key_word : key_words) {
if (pdfsb.length()>0 && pdfsb.toString().contains(key_word)) {
float[] resus = new float[3];
resus[0] = boundingRectange.x +boundingRectange.width * (key_word.length()-1);
resus[1] = boundingRectange.y;
resus[2] = finalI;
arrayLists.get(j).add(resus);
pdfsb ="";
logger.info("找到关键字:"+key_word);
break;
}
}
}
}
}
@Override
public void renderImage(ImageRenderInfo arg0) {
}
@Override
public void endTextBlock() {
}
@Override
public void beginTextBlock() {
}
});
}
} catch (Exception e) {
System.out.println("出现异常"+e.getMessage());
}
return arrayLists;
}
/**
* 获取关键字
*
* @param source
* @param regex
* @return
*/
public static List
if (source.isEmpty()) {
return null;
}
List
if (regex.isEmpty()) {
strList.add(source);
} else {
String[] strArr = source.split(regex);
for (String str : strArr) {
if (!str.isEmpty()) {
strList.add(str);
}
}
}
return strList;
}
另一种利用ExternalSignature算法也可实现,个人更倾向于后者。