commit d6290dccf2e082100a7602d6bf47788c700d672e Author: lijh Date: Tue Mar 10 17:15:26 2026 +0800 first commit diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..dacd518 --- /dev/null +++ b/.classpath @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/.project b/.project new file mode 100644 index 0000000..381d4a1 --- /dev/null +++ b/.project @@ -0,0 +1,17 @@ + + + com.connor.pdf + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..3a21537 --- /dev/null +++ b/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,11 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/bin/.gitignore b/bin/.gitignore new file mode 100644 index 0000000..c2d9872 --- /dev/null +++ b/bin/.gitignore @@ -0,0 +1 @@ +/com/ diff --git a/lib/itext-asian-5.2.0.jar b/lib/itext-asian-5.2.0.jar new file mode 100644 index 0000000..2cc15d2 Binary files /dev/null and b/lib/itext-asian-5.2.0.jar differ diff --git a/lib/itextpdf-5.2.0.jar b/lib/itextpdf-5.2.0.jar new file mode 100644 index 0000000..5c56e77 Binary files /dev/null and b/lib/itextpdf-5.2.0.jar differ diff --git a/lib/spire.pdf.free-5.1.0.jar b/lib/spire.pdf.free-5.1.0.jar new file mode 100644 index 0000000..64d1ff2 Binary files /dev/null and b/lib/spire.pdf.free-5.1.0.jar differ diff --git a/src/com/connor/pdf/TestRenderListener.java b/src/com/connor/pdf/TestRenderListener.java new file mode 100644 index 0000000..8e17ab3 --- /dev/null +++ b/src/com/connor/pdf/TestRenderListener.java @@ -0,0 +1,100 @@ +package com.connor.pdf; + + +import java.awt.Color; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; + +import javax.imageio.ImageIO; + +import com.itextpdf.awt.geom.Rectangle2D; +import com.itextpdf.awt.geom.RectangularShape; + +import com.itextpdf.text.pdf.parser.ImageRenderInfo; +import com.itextpdf.text.pdf.parser.RenderListener; +import com.itextpdf.text.pdf.parser.TextRenderInfo; + + +public class TestRenderListener implements RenderListener { + + + //用来存放文字的矩形 + public List rectText = new ArrayList(); + //用来存放文字 + public List textList = new ArrayList(); + //用来存放文字的y坐标 + public List listY = new ArrayList(); + //用来存放每一行文字的坐标位置 + public List> rows_text_rect = new ArrayList>(); + //PDF文件的路径 + protected String filepath = null; + + public TestRenderListener() { + } + + //step 2,遇到"BT"执行 + @Override + public void beginTextBlock() { + // TODO Auto-generated method stub + } + + //step 3 + + /** + * 文字主要处理方法 + */ + @Override + public void renderText(TextRenderInfo renderInfo) { + //获取文字的下面的矩形 + //Rectangle2D.Float rectBase = renderInfo.getBaseline().getBoundingRectange(); + + + String text = renderInfo.getText(); + if (text.length() > 0) { + RectangularShape rectBase = renderInfo.getBaseline().getBoundingRectange(); + //获取文字下面的矩形 + Rectangle2D.Float rectAscen = renderInfo.getAscentLine().getBoundingRectange(); + //计算出文字的边框矩形 + float leftX = (float) rectBase.getMinX(); + float leftY = (float) rectBase.getMinY() - 1; + float rightX = (float) rectAscen.getMaxX(); + float rightY = (float) rectAscen.getMaxY() + 1; + + Rectangle2D.Float rect = new Rectangle2D.Float(leftX, leftY, rightX - leftX, rightY - leftY); + + System.out.println("text:" + text + "--x:" + rect.x + "--y:" + rect.y + "--width:" + rect.width + "--height:" + rect.height); + + if (listY.contains(rect.y)) { + int index = listY.indexOf(rect.y); + float tempx = rect.x > rectText.get(index).x ? rectText.get(index).x : rect.x; + rectText.set(index, new Rectangle2D.Float(tempx, rect.y, rect.width + rectText.get(index).width, rect.height)); + textList.set(index, textList.get(index) + text); + } else { + rectText.add(rect); + textList.add(text); + listY.add(rect.y); + } + + Map map = new HashMap(); + map.put(text, rect); + rows_text_rect.add(map); + } + } + + //step 4(最后执行的,只执行一次),遇到“ET”执行 + @Override + public void endTextBlock() { + // TODO Auto-generated method stub + } + + //step 1(图片处理方法) + @Override + public void renderImage(ImageRenderInfo renderInfo) { + + } +} diff --git a/src/com/connor/pdf/pdfMain.java b/src/com/connor/pdf/pdfMain.java new file mode 100644 index 0000000..7dc528d --- /dev/null +++ b/src/com/connor/pdf/pdfMain.java @@ -0,0 +1,231 @@ +package com.connor.pdf; + +import com.itextpdf.awt.geom.Rectangle2D; +import com.itextpdf.text.*; +import com.itextpdf.text.pdf.*; +import com.itextpdf.text.pdf.parser.PdfReaderContentParser; + +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.List; +import java.util.concurrent.CountDownLatch; + +import com.spire.pdf.graphics.PdfGraphicsUnit; +import com.spire.pdf.graphics.PdfUnitConvertor; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; + +public class pdfMain { + + public static void main(String[] args) throws Exception { + System.out.println("进入程序开始运行》》》》》》》》》》"); + File file = new File(args[0]); + + + try { + pictureToPdf(args[3], file, args[1], args[2],args[4]); + } catch (Exception e) { + e.printStackTrace(); + } + Thread.sleep(500); +// File file = new File("D://a.pdf"); +// pictureToPdf("900,600,1,100,700,15", file, "D://a.pdf", "D://a.png"); + //图片x位置,图片y位置,图片比例,文字x位置,文字y位置,文字大小 + } + + public static File pictureToPdf(String locationAll, File sourceFile, String outPdfFileName, String picture,String color) { + if (!sourceFile.exists()) { + return null; + } + File outPdfFile = null; + InputStream inputStreamPdf = null; + try { + inputStreamPdf = new FileInputStream(sourceFile); + } catch (Exception e) { + e.printStackTrace(); + } + System.out.println("IN PDF=>" + sourceFile.getAbsolutePath()); + + String length = ""; + String wide = ""; + String type = ""; + String page = ""; + + + if (inputStreamPdf != null) { + PdfReader reader = null; + PdfStamper stamp = null; + try { + outPdfFile = new File(outPdfFileName); + reader = new PdfReader(inputStreamPdf, "PDF".getBytes()); + stamp = new PdfStamper(reader, new FileOutputStream(outPdfFile)); + BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); + PdfContentByte content = null; + // 水印图片 + Image img = null; + int pageSize = reader.getNumberOfPages();// 获取输入文件的页数 + page = pageSize+""; + if (pageSize < 1) { + System.out.println("PDF页数小于0,退出PDF签名"); + return null; + } + PdfDictionary pd = null; + // 新建一个PDF解析对象 + PdfReaderContentParser parser = new PdfReaderContentParser(reader); + int CeroWY = 0; +// if(signoffEntry.getIscero().equals("FROM iPEM") || signoffEntry.getIscero().equals("FROMiPEM")){ +// CeroWY = 2; +// } + for (int index = 1; index <= pageSize; index++) { + + Rectangle rectangle = reader.getPageSizeWithRotation(index); + Float[] fposition = getSize(rectangle); + float pdfW = fposition[0], pdfH = fposition[1]; + System.out.println(String.format("pdfW=%f,pdfH=%f", pdfW, pdfH)); + length = pdfH+""; + wide = pdfW+""; + Image image = Image.getInstance(picture); + String[] locations = locationAll.split(";"); + int count = 0; + String[] location = null; + for (int i = 0; i < locations.length; i++) { + String[] split = locations[i].split(":"); + String[] split2 = split[1].split(","); + if(pdfW > Float.parseFloat(split2[0]) && pdfW < Float.parseFloat(split2[1]) && pdfH > Float.parseFloat(split2[2]) && pdfH < Float.parseFloat(split2[3])) { + System.out.println(split[0]+"匹配---------------------"); + type = split[0]; + location = split[2].split(","); + } + } + if(location == null || location.length <= 0) { + System.out.println(index+":PDF图幅大小未匹配"); + continue ; + } + + content = stamp.getOverContent(index); +// PdfUnitConvertor unitCvtr = new PdfUnitConvertor(); +// float x = unitCvtr.convertUnits(pdfW, PdfGraphicsUnit.Point, PdfGraphicsUnit.Point); +// float y = unitCvtr.convertUnits(pdfH, PdfGraphicsUnit.Point, PdfGraphicsUnit.Point); +// System.out.println(String.format("x=%f,y=%f", x, y)); +// if (x >= 2380 && x <= 2390) { +// float x1 = x; +// float y1 = y; +// x = y1; +// y = x1; +// } +// if (x >= 1680 && x <= 1690 && y >= 2380 && y <= 2390) { +// float x1 = x; +// float y1 = y; +// x = y1; +// y = x1; +// } + SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd"); + Date date = new Date(); + String dateValue = df.format(date); + + image.setAbsolutePosition(Float.parseFloat(location[0]), Float.parseFloat(location[1])); + float originalWidth = image.getWidth(); + float originalHeight = image.getHeight(); + System.out.println(originalWidth); + image.scaleAbsolute(originalWidth * Float.parseFloat(location[2]), originalHeight * Float.parseFloat(location[2])); + + image.setRotationDegrees(0); + content.addImage(image); + + content.beginText(); + + + System.out.println(color+"====================color"); + if(color != null && color.split(",").length == 3) { + String[] split = color.split(","); + System.out.println("split[0]=="+split[0]); + System.out.println("split[1]=="+split[1]); + System.out.println("split[2]=="+split[2]); + content.setColorFill(new BaseColor(Integer.parseInt(split[0]), Integer.parseInt(split[1]), Integer.parseInt(split[2]))); + }else { + content.setColorFill(BaseColor.RED); + } + + + System.out.println("location[5]=="+location[5]); + System.out.println("location[4]=="+location[4]); + System.out.println("location[3]=="+location[3]); + content.setFontAndSize(base, Float.parseFloat(location[5])); + + content.showTextAligned(Element.ALIGN_CENTER, dateValue, + Float.parseFloat(String.valueOf(location[3])), + Float.parseFloat(String.valueOf(location[4])), 0); + + content.setTextMatrix(70, 200); + content.endText(); + } + stamp.close(); + reader.close();// 关闭 + + String finalStr = length+";"+wide+";"+type+";"+page; + System.out.println("finalStr==="+finalStr); + writeStringToPdfMessageFile(finalStr); + + } catch (Exception e) { + e.printStackTrace(); + } finally { + try { + inputStreamPdf.close(); + } catch (Exception ex1) { + ex1.printStackTrace(); + } + } + } + return outPdfFile; + } + + public static Float[] getSize(Rectangle rectangle) { + Float[] sizef = new Float[2]; + float toleft = rectangle.getLeft(); + float tobottom = rectangle.getBottom(); + float toright = rectangle.getRight(); + float totop = rectangle.getTop(); + int rotation = rectangle.getRotation(); + sizef[0] = Float.valueOf(toright - toleft); + sizef[1] = Float.valueOf(totop - tobottom); + +// if (sizef[0].floatValue() < sizef[1].floatValue()) +// { +// float cha = sizef[0].floatValue(); +// sizef[0] = sizef[1]; +// sizef[1] = Float.valueOf(cha); +// } + System.out.println( + "Left=" + toleft + "|Right=" + toright + "|Top=" + totop + "|Bottom=" + tobottom + "|RD=" + rotation); + System.out.println("W=" + sizef[0]); + System.out.println("H=" + sizef[1]); + return sizef; + } + + public static void writeStringToPdfMessageFile(String content) { + // 定义文件路径 + File file = new File( System.getenv("TEMP")+"\\pdfMessage.txt"); + + // 如果文件存在,先删除 + if (file.exists()) { + if (!file.delete()) { + System.err.println("无法删除原有文件: " + file.getAbsolutePath()); + return; + } + } + + // 创建新文件并写入内容 + try (FileWriter writer = new FileWriter(file)) { + writer.write(content); + writer.close(); + System.out.println("文件写入成功: " + file.getAbsolutePath()); + } catch (IOException e) { + System.err.println("写入文件时发生错误: " + e.getMessage()); + } + } + +} \ No newline at end of file