提示:PDF加密是指对PDF文档进行加密保护,以防止未经授权的访问或篡改。通过对PDF文件进行加密,只有授权的人才能查看、编辑或打印文件,从而保护敏感信息和保护文档的完整性。本篇博客详细介绍了pdf加密的实现过程。

文章目录

  • 前言
  • 一、在pom中引入jar依赖
  • 二、编写pdf加密工具类 加密成功后返回ture
  • 三、编写main方法进行测试加密pdf
  • 总结



前言

在某些业务场景下,需要用到将word转换成pdf格式的文件,然后将pdf进行加密处理,在基于这一原理的情况下写了这篇博客来实现pdf加密的功能,并将加密的密码输出在日志中。


提示:以下是本篇文章正文内容,下面案例可供参考

一、在pom中引入jar依赖

引入工具类所需要的依赖包 并刷新maven
<!--	pdf转图片-->
        <dependency>
            <groupId>org.apache.pdfbox</groupId>
            <artifactId>fontbox</artifactId>
            <version>2.0.12</version>
        </dependency>
        <dependency>
            <groupId>org.apache.pdfbox</groupId>
            <artifactId>pdfbox</artifactId>
            <version>2.0.12</version>
        </dependency>

        <!-- 处理文件-->
        <dependency>
            <groupId>com.lowagie</groupId>
            <artifactId>itext</artifactId>
            <version>2.1.7</version>
        </dependency>

二、编写pdf加密工具类 加密成功后返回ture

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.lowagie.text.Document;
import com.lowagie.text.Image;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.PdfWriter;

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.encryption.AccessPermission;
import org.apache.pdfbox.pdmodel.encryption.StandardProtectionPolicy;
import org.apache.pdfbox.rendering.PDFRenderer;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;

/**
 * pdf加密工具类 加密成功后返回ture
 */

public class PdfEncryptionUtil {

    private static final Logger log = LoggerFactory.getLogger(PdfEncryptionUtil.class);

    private static void toPDF(String fileUrl) {
        File file = new File(fileUrl);
        try (PDDocument document = PDDocument.load(file);
             FileOutputStream fos = new FileOutputStream(fileUrl)
        ) {
            PDFRenderer renderer = new PDFRenderer(document);
            Document doc = new Document(null, 0, 0, 0, 0);
            PdfWriter.getInstance(doc, fos);
            String imagePath = null;
            for (int i = 0; i < document.getNumberOfPages(); ++i) {
                FileOutputStream fos22 = null;
                ByteArrayOutputStream out = null;
                try {
                    imagePath = file.getPath() + UUID.randomUUID() + ".png";
                    File imageFile = new File(imagePath);
                    BufferedImage bufferedImage = renderer.renderImageWithDPI(i, 200);
                    out = new ByteArrayOutputStream();
                    ImageIO.write(bufferedImage, "png", out);
                    byte[] m = out.toByteArray();
                    fos22 = new FileOutputStream(imageFile);
                    fos22.write(m, 0, m.length);
                    doc.setPageSize(new Rectangle(bufferedImage.getWidth(), bufferedImage.getHeight()));
                    doc.open();
                    doc.add(Image.getInstance(imagePath));

                } catch (IOException e) {
                    e.printStackTrace();
                    throw new RuntimeException("生成纯图pdf错误");
                } finally {
                    try {
                        if (fos22 != null) {
                            fos22.close();
                        }
                        if (out != null) {
                            out.close();
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                        throw new RuntimeException("流关闭错误!");
                    }
                    // 删除生成得图片 不在这里删除会删除不掉图片得
                    new File(imagePath).delete();
                }
            }
            doc.close();
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("读取初始pdf错误");
        }
    }


    private static String getUUID() throws InterruptedException {
        CountDownLatch count = new CountDownLatch(12);
        StringBuffer sbd = new StringBuffer();
        for (int i = 0; i < 4; i++) {
            Thread thread = new Thread(() -> {
                char ran1 = (char) (Math.random() * (90 - 65 + 1) + 65);
                sbd.append(ran1);
                count.countDown();
            });
            Thread thread1 = new Thread(() -> {
                char ran2 = (char) (Math.random() * (122 - 97 + 1) + 97);
                sbd.append(ran2);
                count.countDown();
            });
            Thread thread2 = new Thread(() -> {
                sbd.append(new Random().nextInt(9));
                count.countDown();
            });
            thread.start();
            thread1.start();
            thread2.start();
        }
        try {
            count.await();
        } catch (Exception e) {
            throw new InterruptedException("线程异常");
        }
        return sbd.substring(0, 10);
    }

    public static boolean toEncryption(String files) {
        //创建一个在内存中表示pdf的类
        PDDocument document = null;
        try {
            //加载现有的PDF文档s
            File file = new File(files);
            //实例化PDDocument
            document = PDDocument.load(file);
            //创建访问权限对象,实例化AccessPermission类
            AccessPermission accessPermission = new AccessPermission();
            //插入/旋转/删除页面
            accessPermission.setCanAssembleDocument(false);
            //从文档提取内容
            accessPermission.setCanExtractContent(false);
            //从文档中提取内容以实现可访问性。
            accessPermission.setCanExtractForAccessibility(false);
            //修改文档
            accessPermission.setCanModify(false);
            //打印
            accessPermission.setCanPrint(true);
            //填写交互表单字段(包括签名字段)
            accessPermission.setCanFillInForm(false);
            //设置用户是否可以添加或修改文本注释和填写交互表单字段,如果canModify()返回true,则创建或修改交互表单字段(包括签名字段)。
            // 注意,如果canFillInForm()返回true,即使这里的参数为false,仍然可以填写交互表单(包括签名字段)。
            accessPermission.setCanModifyAnnotations(false);
            //以降级的格式打印文档
            accessPermission.setCanPrintDegraded(false);
            String uuid = getUUID();
            log.info(file.getName() + "---" + uuid);
            //通过传递所有者密码,用户密码和AccessPermission对象来实例化StandardProtectionPolicy类,第一个密码为执行上面八项操作需要的密码,第二个为打开文件需要的密码
            StandardProtectionPolicy spp = new StandardProtectionPolicy(uuid, "", accessPermission);
            //设置用于加密文档数据的密钥的长度(以位为单位)。默认值为40位
            spp.setEncryptionKeyLength(128);
            //加密文档
            document.protect(spp);
            //保存文档
            document.save(files);
            return true;
        } catch (IOException | InterruptedException | RuntimeException e) {
            e.printStackTrace();
            return false;
        } finally {
            //关闭文件
            if (document != null) {
                try {
                    document.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 调用这里进行加密
     *
     * @param files
     * @return
     */
    public static boolean toDo(String files) {
        toPDF(files);
        // 加密
        return toEncryption(files);
    }
}

三、编写main方法进行测试加密pdf

public static void main(String[] args) {
        // pdf加密
        toDo("C:\\Users\\user\\Desktop\\123456789\\123456123\\123456123.pdf");

    }

java PdfWriter 添加页码 页眉_pdf

总结

以上就是PFD加密的整个过程,在某些业务场景下,需要用到将word转换成pdf格式的文件,然后将pdf进行加密处理,在基于这一原理的情况下写了这篇博客来实现pdf加密的功能,并将加密的密码输出在日志中。所以写下了这篇博客巩固一下盖功能点使用的方法,以及下次遇到相同的需求能够快速开发出来。