在线网站:印章生成器 - Kalvin在线工具 (kalvinbg.cn)
然后对公章进行下载保存
盖章图片:
Keytool是用于管理和证书的工具,位于%JAVA_HOME%/bin目录。
使用JDK的keytool工具
2.2:启动黑窗命令
2.3:生成数字文件
D:\keystore\server.keystore : 就是生成的文件地址
keytool -genkeypair -alias whj -keypass 111111 -storepass 111111 -dname “C=CN,ST=SD,L=QD,O=haier,OU=dev,CN=haier.com” -keyalg RSA -keysize 2048 -validity 3650 -keystore D:\keystore\server.keystore
2.4:转换为p12格式,在命令行输入
注意:这里的路径和上面的路径要保持一直,不能就转不了P12 格式
keytool -importkeystore -srckeystore D:\keystore\server.keystore -destkeystore D:\keystore\whj.p12 -srcalias whj -destalias serverkey -srcstoretype jks -deststoretype pkcs12 -srcstorepass 111111 -deststorepass 111111 -noprompt
-
-
-
com.itextpdf -
itextpdf -
5.5.10 -
-
-
com.itextpdf -
itext-asian -
5.2.0 -
-
-
-
-
org.bouncycastle -
bcprov-jdk15on -
1.49 -
-
-
org.bouncycastle -
bcpkix-jdk15on -
1.49 -
-
功能:
对传入的pdf 文件进行盖章处理
- public class ItextUtil {
-
- /**
- *
- * 功能: keystory密码
- */
-
- public static final char[] PASSWORD = "111111".toCharArray();
-
- /**
- * 单多次签章通用
- *
- * @param src 盖章文件路径
- * @param target 盖章文件输出目标路径
- * @param signatureInfo 盖章实体
- */
- public void sign(String src, String target, SignatureInfo signatureInfo) {
- InputStream inputStream = null;
- FileOutputStream outputStream = null;
- ByteArrayOutputStream result = new ByteArrayOutputStream();
- try {
- inputStream = Files.newInputStream(Paths.get(src));
- ByteArrayOutputStream tempArrayOutputStream = new ByteArrayOutputStream();
- PdfReader reader = new PdfReader(inputStream);
- // 创建签章工具PdfStamper ,最后一个boolean参数是否允许被追加签名
- // false的话,pdf文件只允许被签名一次,多次签名,最后一次有效
- // true的话,pdf可以被追加签名,验签工具可以识别出每次签名之后文档是否被修改
- PdfStamper stamper = PdfStamper.createSignature(reader,
- tempArrayOutputStream, '\0', null, true);
- // 获取数字签章属性对象
- PdfSignatureAppearance appearance = stamper
- .getSignatureAppearance();
- appearance.setReason(signatureInfo.getReason());
- appearance.setLocation(signatureInfo.getLocation());
- // 设置签名的位置,页码,签名域名称,多次追加签名的时候,签名预名称不能一样 图片大小受表单域大小影响(过小导致压缩)
- // 签名的位置,是图章相对于pdf页面的位置坐标,原点为pdf页面左下角
- // 四个参数的分别是,图章左下角x,图章左下角y,图章右上角x,图章右上角y
- //四个参数的分别是,图章左下角x,图章左下角y,图章右上角x,图章右上角y
- appearance.setVisibleSignature(new Rectangle(280, 220, 140, 600), 1, "sig1");
- // 读取图章图片
- Image image = Image.getInstance(signatureInfo.getImagePath());
- appearance.setSignatureGraphic(image);
- appearance.setCertificationLevel(signatureInfo
- .getCertificationLevel());
- // 设置图章的显示方式,如下选择的是只显示图章(还有其他的模式,可以图章和签名描述一同显示)
- appearance.setRenderingMode(signatureInfo.getRenderingMode());
- // 这里的itext提供了2个用于签名的接口,可以自己实现,后边着重说这个实现
- // 摘要算法
- ExternalDigest digest = new BouncyCastleDigest();
- // 签名算法
- ExternalSignature signature = new PrivateKeySignature(
- signatureInfo.getPk(), signatureInfo.getDigestAlgorithm(),
- null);
- // 调用itext签名方法完成pdf签章 //数字签名格式,CMS,CADE
- MakeSignature.signDetached(appearance, digest, signature,
- signatureInfo.getChain(), null, null, null, 0,
- MakeSignature.CryptoStandard.CADES);
-
- inputStream = new ByteArrayInputStream(
- tempArrayOutputStream.toByteArray());
- // 定义输入流为生成的输出流内容,以完成多次签章的过程
- result = tempArrayOutputStream;
-
- outputStream = new FileOutputStream(new File(target));
- outputStream.write(result.toByteArray());
- outputStream.flush();
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- try {
- if (null != outputStream) {
- outputStream.close();
- }
- if (null != inputStream) {
- inputStream.close();
- }
- if (null != result) {
- result.close();
- }
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
-
- }
- public static void main(String[] args) {
- try {
- ItextUtil app = new ItextUtil();
- // 将证书文件放入指定路径,并读取keystore ,获得私钥和证书链
- String pkPath = "src/main/resources/whj.p12";
- KeyStore ks = KeyStore.getInstance("PKCS12");
- ks.load(Files.newInputStream(Paths.get(pkPath)), PASSWORD);
- String alias = ks.aliases().nextElement();
- PrivateKey pk = (PrivateKey) ks.getKey(alias, PASSWORD);
- // 得到证书链
- Certificate[] chain = ks.getCertificateChain(alias);
- //需要进行签章的pdf
-
- String path = "C:\\Users\\ASUS\\Desktop\\sq.pdf";
- // 封装签章信息
- SignatureInfo signInfo = new SignatureInfo();
- signInfo.setReason("牛逼");
- signInfo.setLocation("666");
- signInfo.setPk(pk);
- signInfo.setChain(chain);
- signInfo.setCertificationLevel(PdfSignatureAppearance.NOT_CERTIFIED);
- signInfo.setDigestAlgorithm(DigestAlgorithms.SHA1);
- signInfo.setFieldName("demo");
-
- // 签章图片(网上生成的)
- signInfo.setImagePath("C:\\Users\\ASUS\\Desktop\\字节码\\学习测试30.png");
- signInfo.setRenderingMode(PdfSignatureAppearance.RenderingMode.GRAPHIC);
- 值越大,代表向x轴坐标平移 缩小 (反之,值越小,印章会放大)
- signInfo.setRectllx(100);
- 值越大,代表向y轴坐标向上平移(大小不变)
- signInfo.setRectlly(200);
- // 值越大 代表向x轴坐标向右平移 (大小不变)
- signInfo.setRecturx(150);
- // 值越大,代表向y轴坐标向上平移(大小不变)
- signInfo.setRectury(150);
-
- //签章后的pdf路径
- app.sign(path, "C:\\Users\\ASUS\\Desktop\\字节码\\out.pdf", signInfo);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- public class WaterMark {
- /**
- * pdf生成水印
- *
- * @param srcPdfPath 插入前的文件路径
- * @param tarPdfPath 插入后的文件路径
- * @param WaterMarkContent 水印文案
- * @param numberOfPage 每页需要插入的条数
- * @throws Exception
- */
- public static void addWaterMark(String srcPdfPath, String tarPdfPath, String WaterMarkContent, int numberOfPage) throws Exception {
- PdfReader reader = new PdfReader(srcPdfPath);
- PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(tarPdfPath));
- PdfGState gs = new PdfGState();
- //设置字体
- BaseFont font = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
-
- // 设置透明度
- gs.setFillOpacity(0.4f);
-
- int total = reader.getNumberOfPages() + 1;
- PdfContentByte content;
- for (int i = 1; i < total; i++) {
- content = stamper.getOverContent(i);
- content.beginText();
- content.setGState(gs);
- //水印颜色
- content.setColorFill(BaseColor.DARK_GRAY);
- //水印字体样式和大小
- content.setFontAndSize(font, 35);
- //插入水印 循环每页插入的条数
- for (int j = 0; j < numberOfPage; j++) {
- content.showTextAligned(Element.ALIGN_CENTER, WaterMarkContent, 300, 200 * (j + 1), 30);
- }
- content.endText();
- }
- stamper.close();
- reader.close();
- // 删除源文件,这个可以根据自己的需要来是否删除源文件
- boolean b = deleteFile(srcPdfPath);
- System.out.println("PDF水印添加完成!");
- }
- /**
- *
- * 功能: 删除文件
- * @param path 需要删除的文件路径
- * @return {@link boolean}
- * @author luoheng
- */
-
- public static boolean deleteFile(String path) {
- boolean result = false;
- File file = new File(path);
- if (file.isFile() && file.exists()) {
- int tryCount = 0;
- while (!result && tryCount++ < 10) {
- System.gc();
- result = file.delete();
- }
- }
- return result;
- }
-
-
- }
我们传入需要加水印的pdf,设置对应的格式,数量,字体,以及对应输出的文件地址
- public static void main(String[] args) {
- /**
- * pdf生成水印
- *
- * @param srcPdfPath 需要加印的文件路径
- * @param tarPdfPath 加印后的文件输出路径
- * @param WaterMarkContent 水印文案
- * @param numberOfPage 每页需要插入的条数
- * @throws Exception
- */
- String srcPdfPath = "C:\\Users\\ASUS\\Desktop\\字节码\\out.pdf";
- String tarPdfPath = "C:\\Users\\ASUS\\Desktop\\字节码\\out2.pdf";
- String WaterMarkContent = "程序员小王";
- Integer numberOfPage = 3;
- try {
- // 添加水印
- WaterMark.addWaterMark(srcPdfPath, tarPdfPath, WaterMarkContent, numberOfPage);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
效果图:
如果代码写的有问题,欢迎大家评论交流,进行指点!!!
也希望大家点个关注哦~~~~~~~~