掌握iText:轻松处理PDF文档-高级篇-添加水印

2023-12-13 05:45:48

在这里插入图片描述
在这里插入图片描述

前言

iText作为一个功能强大、灵活且广泛应用的PDF处理工具,在实际项目中发挥着重要作用。通过这些文章,读者可以深入了解如何利用iText进行PDF的创建、编辑、加密和提取文本等操作,为日常开发工作提供了宝贵的参考和指导。

掌握iText:轻松处理PDF文档-基础篇

掌握iText:轻松处理PDF文档-进阶篇

需求描述

可能你会经常遇到类似的场景, 为了保护敏感信息和版权,需要在PDF文件上添加水印,在类似这样的需求上再作一个延伸,可能就是两种情况:第一种,程序在处理数据后,生成新的pdf文档的同时增加水印;第二种,pdf文档已经存在,需要在导出的时候,给已经存在的pdf文档增加水印。那么这两种需求,如果使用iText5,应该怎么实现呢?

iText的依赖

在maven的pom.xml中配置:

<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itextpdf</artifactId>
    <version>5.5.13.3</version>
</dependency>
<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itext-asian</artifactId>
    <version>5.2.0</version>
</dependency>

生成新的pdf文档的同时增加水印

程序在处理数据后,生成新的pdf文档的同时增加水印,具体的步骤如下:
1.创建一个大小为A4纸、横向显示的PDF文档。
2.创建PdfWriter对象,用于将文档内容写入到PDF文件中。
3.打开文档。
4.创建第一页(可省略)。
5.获取水印的PdfContentByte对象。
6.调用setWaterMar方法,在水印画布上设置水印内容和样式。
7.循环100次,在文档中添加一段文字。
8.关闭文档和PdfWriter对象。
9.输出成功生成PDF文件的消息。
其中 setWaterMar 方法封装了具体的水印设置逻辑,具体逻辑如下:
1.检查水印画布是否为空。
2.开始设置水印文本。
3.设置水印的透明度。
4.创建PdfGState对象,设置填充字体的不透明度为0.4f。
5.设置水印的字体和大小。
6.设置水印的对齐方式、位置和旋转角度。
7.设置水印的颜色。
8.结束设置水印文本。

// 往pdf文档中写入文本内容时,添加水印
@Test
public void test() throws FileNotFoundException, DocumentException {
    //实现A4纸页面 并且横向显示(不设置则为纵向)
    Document document = new Document(PageSize.A4.rotate());
    PdfWriter pdfWriter = PdfWriter.getInstance(document, new FileOutputStream("e:/pdf-test/test-v1.pdf"));
    // 打开文档
    document.open();
    // 创建第一页(如果只有一页的话,这一步可以省略)
    document.newPage();
    // 加入水印,水印内容:x+y=z
    PdfContentByte waterMar = pdfWriter.getDirectContentUnder();
    this.setWaterMar(waterMar, "x+y=z");
    for (int i = 0; i < 100; i++) {
        // 加入文档内容
        document.add(new Paragraph("my first pdf demo"));
    }
    // 关闭文档
    document.close();
    pdfWriter.close();
}
private void setWaterMar(PdfContentByte waterMar, String waterContent) {
    if (waterMar == null) {
        return;
    }
    // 开始设置水印
    waterMar.beginText();
    // 设置水印透明度
    PdfGState gs = new PdfGState();
    // 设置填充字体不透明度为0.4f
    gs.setFillOpacity(0.4f);
    try {
        // 设置水印字体参数及大小(字体参数,字体编码格式,是否将字体信息嵌入到pdf中(一般不需要嵌入),字体大小)
        waterMar.setFontAndSize(BaseFont.createFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.NOT_EMBEDDED), 60);
        // 设置透明度
        waterMar.setGState(gs);
        // 设置水印对齐方式 水印内容 X坐标 Y坐标 旋转角度
        waterMar.showTextAligned(Element.ALIGN_RIGHT, waterContent, 500, 430, 45);
        // 设置水印颜色
        waterMar.setColorFill(BaseColor.GRAY);
        //结束设置
        waterMar.endText();
        waterMar.stroke();
    } catch (IOException e) {
        e.printStackTrace();
    } catch (DocumentException e) {
        throw new RuntimeException(e);
    }
}

效果如下:
在这里插入图片描述

给已经生成的pdf文档增加水印

1.指定输入和输出的 PDF 文件路径。
2.创建 PdfReader 对象,用于读取原始 PDF 文件。
3.创建 PdfStamper 对象,用于添加水印,并传入原始 PDF 文件和输出 PDF 文件的路径。
4.获取原始 PDF 文件的页数。
5.加载自定义字体 HongLeiXingShuJianTi-2.otf。我这里是从字体天下网(https://www.fonts.net.cn)下载一个字体,可以使用你拥有的其他字体,需要注意字体版权问题,我下载这个是商用免费。
6.设置水印的字体大小和旋转角度。
7.准备向每一页添加水印。
8.循环迭代每一页,获取当前页的 PdfContentByte 对象,即用于绘制内容的画布。
9.调用 setWaterMar 方法,在当前页的画布上添加水印。
10.关闭 PdfStamper 和 PdfReader 对象,释放资源。
11.输出一条成功添加水印的消息。
其中 setWaterMar 方法封装了具体的水印设置逻辑,具体逻辑如下:
1.设置水印的填充颜色为浅灰色。
2.开始绘制文本。
3.设置文本的字体和大小。
4.使用嵌套循环,将水印文本重复添加到当前页的多个位置上。
5.结束绘制文本。

@Test
public void test2() {
    try {
        // 输入PDF文件路径
        String inputFile = "e:/pdf-test/test.pdf";
        // 输出PDF文件路径
        String outputFile = "e:/pdf-test/test-v2.pdf";
        // 创建PdfReader对象读取原始PDF文件
        PdfReader reader = new PdfReader(inputFile);
        // 创建PdfStamper对象,用于添加水印
        PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(outputFile));
        // 设置水印属性
        int n = reader.getNumberOfPages();
        URL resource = getClass().getClassLoader().getResource("HongLeiXingShuJianTi-2.otf");
        FontFactory.register(resource.getPath(), "HongLeiXingShuJianTi-2.otf");
        BaseFont baseFont = BaseFont.createFont("HongLeiXingShuJianTi-2.otf", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
        float fontSize = 20; // 设置字体大小
        float watermarkAngle = 10; // 设置水印旋转角度
        PdfContentByte watermark;
        // 添加水印到每一页
        for (int i = 1; i <= n; i++) {
            watermark = stamper.getOverContent(i);
            this.setWaterMar(watermark, "凡夫编程", baseFont, fontSize, watermarkAngle);
        }
        // 关闭PdfStamper和PdfReader对象
        stamper.close();
        reader.close();
        System.out.println("水印已添加到PDF文档中。");
    } catch (DocumentException | IOException e) {
        e.printStackTrace();
    }
}
private void setWaterMar(PdfContentByte watermark, String waterContent, BaseFont baseFont, float fontSize, float watermarkAngle) {
    watermark.setColorFill(BaseColor.LIGHT_GRAY);
    watermark.beginText();
    watermark.setFontAndSize(baseFont, fontSize);
    for (int m = 0; m < 10; m++) {
        for (int n = 0; n < 10; n++) {
            watermark.showTextAligned(Element.ALIGN_LEFT, "凡夫编程", 10 + m * 150, 10 + n * 100, watermarkAngle);
        }
    }
    watermark.endText();
}

效果如下:
在这里插入图片描述

写入与读取元数据

写入元数据:

1.创建一个空白的PDF文档对象。
2.创建PdfWriter对象,用于将文档内容写入到PDF文件中,并指定输出文件路径。
3.打开文档。
4.向文档中添加一段文字内容。
5.使用addCreator方法设置文档的创建者信息。
6.使用addTitle方法设置文档的标题信息。
7.使用addAuthor方法设置文档的作者信息。
8.关闭文档。

@Test
public void test6() {
    Document document = new Document();
    try {
        // 设置加密算法和用户/所有者密码
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("e:/pdf-test/test-v6.pdf"));
        document.open();
        // 添加一些内容到文档中
        document.add(new Paragraph("This is pdf document."));
        document.addCreator("fanfu");
        document.addTitle("test-pdf");
        document.addAuthor("gaoxing");
        document.close();
    } catch (DocumentException | IOException e) {
        e.printStackTrace();
    }
}

读取元数据:

1.创建一个PdfReader对象,用于读取指定PDF文件("e:/pdf-test/test-v6.pdf")的内容。
2.调用getInfo方法获取PDF文档的元数据信息,并将其存储在一个HashMap对象中。
3.使用for循环遍历HashMap中的键值对,打印每个键对应的值。
@Test
public void test7() {
    try {
        // 设置加密算法和用户/所有者密码
        PdfReader pdfReader = new PdfReader(new FileInputStream("e:/pdf-test/test-v6.pdf"));
        HashMap<String, String> info = pdfReader.getInfo();
        for (String key : info.keySet()) {
            System.out.println(info.get(key));
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

文章来源:https://blog.csdn.net/fox9916/article/details/134956946
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。