验证签名,从证书中获取公钥来验证签名是否正确
+ * + * @param data 传输的数据 + * @param sign 对传输数据的签名 + * @param certificateContent 证书内容的2进制形式 + */ + public static boolean verifySign(byte[] data, byte[] sign, String certificateContent) throws Exception { + X509Certificate certificate = (X509Certificate) getCertificate(certificateContent); + Signature signature = Signature.getInstance(certificate.getSigAlgName()); + // 由证书初始化签名,使用了证书中的公钥 + signature.initVerify(certificate); + signature.update(data); + return signature.verify(sign); + } + + /** + *从证书文件读取证书.'.crt'和'.cer'文件都可以读取 .cer是IE导出的公钥证书(der格式)
+ * @param certificatePath 证书文件路径:可以直接加载指定的文件,例如"file:C:/kft.cer" + */ + private static Certificate getCertificate(String certificatePath) throws Exception { + File certificate = new File(certificatePath); + if (certificate == null || (certificate.exists() && certificate.isDirectory())) { + throw new IllegalArgumentException("certificatePath[" + certificatePath + "]必须是一个已经存在的文件,不能为空,且不能是一个文件夹"); + } + InputStream inputStream = null; + try { + inputStream = new FileInputStream(certificate); + // 实例化证书工厂 + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + Certificate cert = cf.generateCertificate(inputStream); + return cert; + } finally { + if (inputStream != null) { + inputStream.close(); + } + } + } +} diff --git a/src/main/java/com/yumaolin/util/PDFBoxUtil/ITextUtil.java b/src/main/java/com/yumaolin/util/PDFBoxUtil/ITextUtil.java new file mode 100644 index 0000000..61e8211 --- /dev/null +++ b/src/main/java/com/yumaolin/util/PDFBoxUtil/ITextUtil.java @@ -0,0 +1,124 @@ +package com.yumaolin.util.PDFBoxUtil; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.Map; + +import com.itextpdf.text.BaseColor; +import com.itextpdf.text.Document; +import com.itextpdf.text.DocumentException; +import com.itextpdf.text.Font; +import com.itextpdf.text.Paragraph; +import com.itextpdf.text.pdf.AcroFields; +import com.itextpdf.text.pdf.BaseFont; +import com.itextpdf.text.pdf.PdfReader; +import com.itextpdf.text.pdf.PdfStamper; +import com.itextpdf.text.pdf.PdfWriter; + +public class ITextUtil { + + /** + *创建PDF文件
+ * @param filePath + */ + public void createPDFFile(String filePath) { + try{ + Document doc = new Document(); + String fontPath = "C:\\Windows\\Fonts\\MSYHMONO.ttf"; + PdfWriter.getInstance(doc, new FileOutputStream(filePath)); + doc.open(); + BaseFont bfChinese = BaseFont.createFont(fontPath,BaseFont.IDENTITY_H,BaseFont.EMBEDDED); + Font fontChinese = new Font(bfChinese, 12, Font.NORMAL, BaseColor.GREEN); + Paragraph pf = new Paragraph("protocolNo|custIdenNo|custName", fontChinese); + //pf.add(new Paragraph("我们的家好大的家", fontChinese)); + //pf.add(new Paragraph("sfsfsf")); + doc.add(pf); + doc.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void parsePDFFile(String oldPath,String newPath,Map创建PDF文件
+ * @param filePath + */ + public void createPDFFile(String filePath) { + try(PDDocument document = new PDDocument()){ + PDPage page = new PDPage(); + document.addPage(page); + PDAcroForm acroForm = new PDAcroForm(document); + document.getDocumentCatalog().setAcroForm(acroForm); + // Add and set the resources and default appearance at the form level + PDFont formFont = PDType0Font.load(document, new FileInputStream( + "C:\\Windows\\Fonts\\MSYHMONO.ttf"), false); + final PDResources resources = new PDResources(); + acroForm.setDefaultResources(resources); + + final String fontName = resources.add(formFont).getName(); + + // Acrobat sets the font size on the form level to be + // auto sized as default. This is done by setting the font size to '0' + acroForm.setDefaultResources(resources); + String defaultAppearanceString = "/" + fontName + " 0 Tf 0 g"; + + PDTextField textBox = new PDTextField(acroForm); + textBox.setPartialName("SampleField"); + textBox.setDefaultAppearance(defaultAppearanceString); + acroForm.getFields().add(textBox); + + // Specify the widget annotation associated with the field + PDAnnotationWidget widget = textBox.getWidgets().get(0); + PDRectangle rect = new PDRectangle(50, 700, 200, 50); + widget.setRectangle(rect); + widget.setPage(page); + page.getAnnotations().add(widget); + + // set the field value. Note that the last character is a turkish capital I with a dot, + // which is not part of WinAnsiEncoding + textBox.setValue("protocolNo"); + + document.save(filePath); + /*PDFont font = PDType0Font.load(document,new FileInputStream("C:\\Windows\\Fonts\\MSYHMONO.ttf"),false); + //PDFont font = PDType1Font.COURIER; + PDPageContentStream content = new PDPageContentStream(document, page); + content.beginText(); + content.setFont(font, 12); + content.newLineAtOffset(100, 700); + content.showText("protocolNo"); + content.endText(); + content.close();*/ + document.save(filePath); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + *读取PDF文件
+ * @param filePath + */ + public void readPDF(String filePath) { + PDDocument helloDocument = null; + try { + helloDocument = PDDocument.load(new File(filePath)); + PDFTextStripper textStripper = new PDFTextStripper(); + System.out.println(textStripper.getText(helloDocument)); + helloDocument.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + /** + *替换PDF文件中的某个字符串
+ * @param inputFile + * @param outputFile + * @param strToFind + * @param message + * @throws IOException + */ + public void replaceText(String inputFile, String outputFile, String strToFind, String message) + throws IOException { + // the document + PDDocument document = null; + try{ + document = PDDocument.load(new File(inputFile)); + //PDFTextStripper stripper=new PDFTextStripper("ISO-8859-1"); + PDPageTree pages = document.getPages(); + PDResources resources = new PDResources(); + PDFont font = PDType0Font.load(document,new FileInputStream("C:\\Windows\\Fonts\\MSYHMONO.ttf"),false); + resources.add(font); + for (int i = 0; i < document.getNumberOfPages(); i++) { + PDPage page = (PDPage) pages.get(i); + page.setResources(resources); + PDFStreamParser parser = new PDFStreamParser(page); + parser.parse(); + List tokens = parser.getTokens(); + System.out.println(tokens); + for (int j = 0; j < tokens.size(); j++) { + Object next = tokens.get(j); + System.out.println(next); + if (next instanceof Operator) { + // Tj and TJ are the two operators that display + // strings in a PDF + String operatorName = ((Operator) next).getName(); + if (operatorName.equals("Tj")) { + // Tj takes one operator and that is the string + // to display so lets update that operator + COSString previous = (COSString) tokens.get(j-1); + byte[] bytes = previous.getBytes(); + String string = new String(bytes,Charsets.UTF_8); + System.out.println(string); + System.out.println(previous.getASCII()); + System.out.println(previous.getForceHexForm()); + System.out.println(previous.getCOSObject()); + System.out.println(previous.getString()); + System.out.println(previous.getClass()); + string = string.replaceFirst(strToFind, message); + previous.setValue(string.getBytes(Charsets.UTF_8)); + } else if (operatorName.equals("TJ")) { + COSArray previous = (COSArray) tokens.get(j - 1); + for (int k = 0; k < previous.size(); k++) { + Object arrElement = previous.getObject(k); + if (arrElement instanceof COSString) { + COSString cosString = (COSString) arrElement; + String string = cosString.getString(); + string = string.replaceFirst(strToFind, message); + cosString.setValue(string.getBytes(Charsets.UTF_8)); + } + } + } + } + } + // now that the tokens are updated we will replace the + // page content stream. + PDStream updatedStream = new PDStream(document); + OutputStream out = updatedStream.createOutputStream(); + ContentStreamWriter tokenWriter = new ContentStreamWriter(out); + tokenWriter.writeTokens(tokens); + page.setContents(updatedStream); + out.close(); + } + document.save(outputFile); + }finally{ + if(document != null){ + document.close(); + } + } + } + + public static void main(String[] args) throws IOException { + PDFUtil pdfUtil = new PDFUtil(); + pdfUtil.createPDFFile("D:\\test.PDF"); + pdfUtil.replaceText("D:\\test.PDF","D:\\newTest.PDF","protocolNo","合同编号"); + } +} diff --git a/src/main/java/com/yumaolin/util/PDFBoxUtil/PositionRenderListener.java b/src/main/java/com/yumaolin/util/PDFBoxUtil/PositionRenderListener.java new file mode 100644 index 0000000..2fff0d2 --- /dev/null +++ b/src/main/java/com/yumaolin/util/PDFBoxUtil/PositionRenderListener.java @@ -0,0 +1,77 @@ +package com.yumaolin.util.PDFBoxUtil; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +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; + +/** + * pdf渲染监听,当找到渲染的文本时,得到文本的坐标x,y,w,h + * @user : caoxu-yiyang@qq.com + * @date : 2016年11月9日 + */ +public class PositionRenderListener implements RenderListener{ + + private List