1.添加maven依赖
<dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf</artifactId> <version>5.5.6</version> </dependency>
2.获得透明的png格式的电子印章图片的工具类
package lucky.aozhan.user.utils; import javax.imageio.ImageIO; import javax.swing.*; import java.awt.*; import java.awt.image.BufferedImage; import java.io.*; public class PNGchange { public static void main(String[] args) { System.out.println(transferAlpha2File("D:\resource\yinzhang\aozhanyzimg.png", "D:\resource\yinzhang\aozhanyzimg_1.png")); } public static boolean transferAlpha2File(String imgSrc, String imgTarget) { File file = new File(imgSrc); InputStream is = null; boolean result = false; try { is = new FileInputStream(file); // 如果是MultipartFile类型,那么自身也有转换成流的方法:is = file.getInputStream(); BufferedImage bi = ImageIO.read(is); Image image = (Image) bi; ImageIcon imageIcon = new ImageIcon(image); BufferedImage bufferedImage = new BufferedImage(imageIcon.getIconWidth(), imageIcon.getIconHeight(), BufferedImage.TYPE_4BYTE_ABGR); Graphics2D g2D = (Graphics2D) bufferedImage.getGraphics(); g2D.drawImage(imageIcon.getImage(), 0, 0, imageIcon.getImageObserver()); int alpha = 0; for (int j1 = bufferedImage.getMinY(); j1 < bufferedImage.getHeight(); j1++) { for (int j2 = bufferedImage.getMinX(); j2 < bufferedImage.getWidth(); j2++) { int rgb = bufferedImage.getRGB(j2, j1); int R = (rgb & 0xff0000) >> 16; int G = (rgb & 0xff00) >> 8; int B = (rgb & 0xff); if (((255 - R) < 30) && ((255 - G) < 30) && ((255 - B) < 30)) { rgb = ((alpha + 1) << 24) | (rgb & 0x00ffffff); } bufferedImage.setRGB(j2, j1, rgb); } } g2D.drawImage(bufferedImage, 0, 0, imageIcon.getImageObserver()); result = ImageIO.write(bufferedImage, "png", new File(imgTarget));// 直接输出文件 } catch (Exception e) { e.printStackTrace(); result = false; } finally { if (is != null) { try { is.close(); } catch (IOException e) { // TODO Auto-generated catch block } } } return result; } public static byte[] transferAlpha2Byte(String imgSrc) { ByteArrayOutputStream byteArrayOutputStream = null; File file = new File(imgSrc); InputStream is = null; byte[] result = null; try { is = new FileInputStream(file); // 如果是MultipartFile类型,那么自身也有转换成流的方法:is = file.getInputStream(); BufferedImage bi = ImageIO.read(is); Image image = (Image) bi; ImageIcon imageIcon = new ImageIcon(image); BufferedImage bufferedImage = new BufferedImage(imageIcon.getIconWidth(), imageIcon.getIconHeight(), BufferedImage.TYPE_4BYTE_ABGR); Graphics2D g2D = (Graphics2D) bufferedImage.getGraphics(); g2D.drawImage(imageIcon.getImage(), 0, 0, imageIcon.getImageObserver()); int alpha = 0; for (int j1 = bufferedImage.getMinY(); j1 < bufferedImage.getHeight(); j1++) { for (int j2 = bufferedImage.getMinX(); j2 < bufferedImage.getWidth(); j2++) { int rgb = bufferedImage.getRGB(j2, j1); int R = (rgb & 0xff0000) >> 16; int G = (rgb & 0xff00) >> 8; int B = (rgb & 0xff); if (((255 - R) < 30) && ((255 - G) < 30) && ((255 - B) < 30)) { rgb = ((alpha + 1) << 24) | (rgb & 0x00ffffff); } bufferedImage.setRGB(j2, j1, rgb); } } g2D.drawImage(bufferedImage, 0, 0, imageIcon.getImageObserver()); byteArrayOutputStream = new ByteArrayOutputStream(); ImageIO.write(bufferedImage, "png", byteArrayOutputStream);//转换成byte数组 result = byteArrayOutputStream.toByteArray(); } catch (Exception e) { e.printStackTrace(); } finally { if (is != null) { try { is.close(); } catch (IOException e) { // TODO Auto-generated catch block } } if (byteArrayOutputStream != null) { try { byteArrayOutputStream.close(); } catch (IOException e) { // TODO Auto-generated catch block } } } return result; } }
3.添加印章的工具类
package lucky.aozhan.user.utils; import com.itextpdf.text.DocumentException; import com.itextpdf.text.Image; import com.itextpdf.text.pdf.PdfContentByte; import com.itextpdf.text.pdf.PdfReader; import com.itextpdf.text.pdf.PdfStamper; 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 java.awt.geom.Rectangle2D; import java.io.FileOutputStream; import java.io.IOException; public class AddYingZhangImgUtil { public static void main(String[] args) throws IOException, DocumentException { // 模板文件路径 String templatePath = "D:\resource\yinzhang\p869.pdf"; // 生成的文件路径 String targetPath = "D:\resource\yinzhang\p869_new.pdf"; // 图片路径, 需要png透明图片,否则会覆盖文字 String imagePath = "D:\resource\yinzhang\aozhanyzimg_1.png"; addSignImg(templatePath, targetPath, imagePath, "INSPECTION", null); } /** * 根据pdf中的关键字,获取文字的绝对位置,并进行签章 * * @param inputPath 未处理pdf * @param targetPath 已签章pdf地址 * @param imagePath 签章图片地址 * @param inputPath pdf中的关键字 * @param pageNum pdf页数,可传null,默认设置最大页数 * @return float的x与y值 * @throws IOException */ private static void addSignImg(String inputPath, String targetPath, final String imagePath, final String keyWord, Integer pageNum) throws IOException, DocumentException { PdfReader pdfReader = new PdfReader(inputPath); // 读图片 final Image image = Image.getInstance(imagePath); // 根据域的大小缩放图片 image.scaleToFit(100, 100); image.setRotationDegrees(15);//设置印章图片的旋转角度 if (null == pageNum) { pageNum = pdfReader.getNumberOfPages(); } new PdfReaderContentParser(pdfReader).processContent(pageNum, new RenderListener() { public void beginTextBlock() { } public void renderText(TextRenderInfo textRenderInfo) { String text = textRenderInfo.getText(); if (text != null && text.contains(keyWord)) { // 文字在page中的横坐标、纵坐标 com.itextpdf.awt.geom.Rectangle2D.Float textFloat = textRenderInfo.getBaseline().getBoundingRectange(); float x = textFloat.x; float y = textFloat.y; // 设置图片位置 image.setAbsolutePosition(x + 50f, y - 30f); } } public void endTextBlock() { } public void renderImage(ImageRenderInfo renderInfo) { } }); // 获取操作的页面 PdfStamper stamper = new PdfStamper(pdfReader, new FileOutputStream(targetPath)); PdfContentByte under = stamper.getOverContent(pageNum); under.addImage(image); stamper.close(); pdfReader.close(); } }
4.效果图
参考文献:
https://blog.csdn.net/weixin_39515661/article/details/90402601?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task