java PDF电子签章、文件拆分、文件合并

java PDF电子签章、文件拆分、文件合并

日常工作常用问题记录,本次使用的是PDFBox实现的

pom依赖

<!-- https://mvnrepository.com/artifact/org.apache.pdfbox/fontbox -->
<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>fontbox</artifactId>
    <version>2.0.24</version>
</dependency>

PDF电子签章


电子签章分为二种,一种是图片盖章,一种是动态插文本值
图片盖章一般用于公章、或一些固定需求
动态文本插值一般用于读取数据动态填充到文件中

图片盖戳

@Test
    public void img() throws IOException {
        //文件地址
        File file = new File("C:\\Users\\0\\Desktop\\10.pdf");
        //加载PDF文件
        PDDocument doc = PDDocument.load(file);
        //获取文件页数
        PDPage page = doc.getPage(1);
        //加载图片与文件对象
        PDImageXObject pdImage = PDImageXObject.createFromFile("C:\\Users\\0\\Desktop\\1.png",doc);
        //加载内容流属性,
        //参数1:文件对象、2:操作页对象、3:操作方式,分为覆盖、追加、加载前追加,一般用加载前追加、4:默认false,5:默认true
        PDPageContentStream contents = new PDPageContentStream(doc, page, PDPageContentStream.AppendMode.PREPEND,false,true);
        //盖章的PDF文件定位坐标
        contents.drawImage(pdImage, 270, 440);
        //关闭流
        contents.close();
        //重新生成新的盖章文件
        doc.save("C:\\Users\\0\\Desktop\\2.pdf");
        //关闭流
        doc.close();
    }

文本插值

@Test
    public void pdfTest() throws Exception {
        File file = new File("C:\\Users\\0\\Desktop\\10.pdf");
        PDDocument doc = PDDocument.load(file);
        PDPage page = doc.getPage(1 );
        //加载字体,必须用支持中文的字体,不然插中文值会报错
        PDFont font = PDType0Font.load(doc, new File("C:\\Windows\\Fonts\\simhei.ttf"));
        PDPageContentStream contentStream = new PDPageContentStream(doc, page,PDPageContentStream.AppendMode.PREPEND,true,true);
        //开启文本插值
        contentStream.beginText();
        //插值坐标
        float tx =  202.136F;
        float ty =  8.35F;
        contentStream.newLineAtOffset(tx, ty);
        //字体大小
        contentStream.setFont(font, 12);
        //阅读间隙
        contentStream.setLeading(14f);
        String text1 = "值1";
        String text11 = "值2";
        String text2 = "值3";
        String text3 = "值4";
        contentStream.showText(text1);
        newLineNum(contentStream,1);
        contentStream.showText(text11);
        newLineNum(contentStream,2);
        contentStream.showText(text2);
        newLineNum(contentStream,3);
        contentStream.showText(text3);
        newLineNum(contentStream,3);
        //关闭文本插值
        contentStream.endText();
        contentStream.close();
        doc.save(new File("C:\\Users\\0\\Desktop\\11.pdf"));
        doc.close();
    }


    private void newLineNum(PDPageContentStream contentStream, int num) throws IOException {
        for (int i = 1; i <= num; i++) {
            contentStream.newLine();
        }
    }

文件拆分

一般用于文件需要拆分成多份文件需求

@Test
    public void PdfFenGe() throws IOException, JSONException {
        File file = new File("C:\\Users\\0\\Desktop\\-222.pdf");
        PDDocument document = PDDocument.load(file);
        PDDocument document1 = new PDDocument();
        Splitter splitter = new Splitter();
        //分割源文件,List中每页是一条数据
        List<PDDocument> Pages = splitter.split(document);
        //一般用于实际业务需求或者前端传递的规则进行循环拼成多个PDDocument对象进行保存即可
        for (PDDocument page : Pages) {
            document1.addPage(page.getPage(0));
        }
        document1.save("C:\\Users\\0\\Desktop\\-222.pdf");
        document.close();
        document1.close();
    }

文件合并

一般用于多个文件需要合成一个文件时使用

@Test
    public void heBing() throws IOException {
        //读文件
        File file1 = new File("C:\\Users\\0\\Desktop\\DM1.pdf");
        File file2 = new File("C:\\Users\\0\\Desktop\\-222.pdf");
        //PDF文件合并
        PDFMergerUtility PDFmerger = new PDFMergerUtility();
        //添加多个文件到合并对象中
        PDFmerger.addSource(file1);
        PDFmerger.addSource(file2);
        //设置一个临时存储位置
        PDFmerger.setDestinationFileName(System.getProperty("user.dir") + "\\合并文件-临时文件.pdf");
        //开始加载合并
        PDFmerger.mergeDocuments(MemoryUsageSetting.setupMainMemoryOnly());
        ByteArrayOutputStream stream = new ByteArrayOutputStream();
        //读取刚刚的临时文件
        PDDocument document = PDDocument.load(new File(System.getProperty("user.dir") + "\\合并文件-临时文件.pdf"));
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        //输出到指定的流中或者直接输出文件
        document.save(byteArrayOutputStream);
        document.close();
        //如果不需要后续操作,就不需要删除文件,我们需要流重新上传文件,所以删除临时文件
        if (new File(PDFmerger.getDestinationFileName()).exists()){
            new File(PDFmerger.getDestinationFileName()).delete();
        }
    }

该文章到这里就结束了,对大家有帮助希望点赞评论下,有问题可以评论区提出来

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java可以通过使用第三方库来实现PDF电子章的功能。其中比较常用的有iText和PDFBox。 iText是一个广泛使用的PDF文档处理库,可以在PDF文档中添加数字名。以下是使用iText实现PDF电子章的步骤: 1. 加载PDF文件并创建名区域 ``` PdfReader reader = new PdfReader("original.pdf"); FileOutputStream os = new FileOutputStream("signed.pdf"); PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0'); PdfSignatureAppearance appearance = stamper.getSignatureAppearance(); appearance.setImage(Image.getInstance("signature.png")); appearance.setReason("I am the author"); appearance.setLocation("China"); ``` 2. 创建数字名 ``` PrivateKey privateKey = (PrivateKey) keystore.getKey("alias", "password".toCharArray()); Certificate[] chain = keystore.getCertificateChain("alias"); PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED); dic.setReason(appearance.getReason()); dic.setLocation(appearance.getLocation()); dic.setContact(appearance.getContact()); dic.setDate(new PdfDate(appearance.getSignDate())); appearance.setCrypto(privateKey, chain, null, PdfSignatureAppearance.WINCER_SIGNED); appearance.setSignatureGraphic(Image.getInstance(signatureGraphic)); appearance.setRenderingMode(PdfSignatureAppearance.RenderingMode.GRAPHIC); appearance.setVisibleSignature(new Rectangle(36, 748, 144, 780), 1, "sig"); PdfSignature dic2 = new PdfSignature(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED); dic2.setReason(appearance.getReason()); dic2.setLocation(appearance.getLocation()); dic2.setContact(appearance.getContact()); dic2.setDate(new PdfDate(appearance.getSignDate())); PdfSignatureAppearance appearance2 = PdfStamper.createSignature(reader, null, '\0'); appearance2.setVisibleSignature(new Rectangle(36, 748, 144, 780), 1, "sig"); appearance2.setCrypto(privateKey, chain, null, PdfSignatureAppearance.WINCER_SIGNED); PdfSignature dic3 = new PdfSignature(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED); dic3.setReason(appearance.getReason()); dic3.setLocation(appearance.getLocation()); dic3.setContact(appearance.getContact()); dic3.setDate(new PdfDate(appearance.getSignDate())); appearance2.setSignatureGraphic(Image.getInstance(signatureGraphic)); appearance2.setRenderingMode(PdfSignatureAppearance.RenderingMode.GRAPHIC); PdfDictionary dic4 = new PdfDictionary(); dic4.put(PdfName.CONTENTS, new PdfString("test".getBytes())); ``` 3. 名并保存PDF文件 ``` PdfSignature dic5 = new PdfSignature(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED); dic5.setReason(appearance.getReason()); dic5.setLocation(appearance.getLocation()); dic5.setContact(appearance.getContact()); dic5.setDate(new PdfDate(appearance.getSignDate())); appearance4.setCrypto(privateKey, chain, null, PdfSignatureAppearance.WINCER_SIGNED); appearance4.setSignatureGraphic(Image.getInstance(signatureGraphic)); appearance4.setRenderingMode(PdfSignatureAppearance.RenderingMode.GRAPHIC); PdfDictionary dic6 = new PdfDictionary(); dic6.put(PdfName.CONTENTS, new PdfString("test".getBytes())); PdfDictionary dic7 = new PdfDictionary(); dic7.put(PdfName.CONTENTS, new PdfString("test".getBytes())); ``` 以上就是使用iText实现PDF电子章的基本步骤。值得注意的是,章的过程中需要使用数字证书,确保章的真实性和合法性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值