Java给PDF上水印

我下载了个作为示例的PDF文件:

代码

利用PDFBox

<dependency>
    <groupId>org.apache.pdfbox</groupId>
    <artifactId>pdfbox</artifactId>
    <version>2.0.23</version>
</dependency>
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Element;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDType0Font;
import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;
import org.apache.pdfbox.util.Matrix;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class PDFWaterMark {

    public static void main(String[] args) throws Exception {
        usePDFBox();
    }

    private static void usePDFBox() throws Exception {
        File sourcePDF = new File("20210331165837838.pdf");
        File targetPDF = new File("20210331165837838-watermark.pdf");
        PDDocument doc = PDDocument.load(sourcePDF);
        doc.setAllSecurityToBeRemoved(true);
        // 水印文字
        String ts = "给PDF加水印";
        for(PDPage page : doc.getPages()){
            // 透明度
            PDExtendedGraphicsState graphicsState = new PDExtendedGraphicsState();
            graphicsState.setNonStrokingAlphaConstant(0.2f);
            graphicsState.setAlphaSourceFlag(true);

            PDPageContentStream cs = new PDPageContentStream(doc, page, PDPageContentStream.AppendMode.APPEND, true, true);
            cs.setGraphicsStateParameters(graphicsState);
            cs.setNonStrokingColor(100,0,40, 0); // CMYK颜色
            cs.beginText();
            // 引入外部字体
            cs.setFont(PDType0Font.load(doc, new File("C:\Windows\Fonts\simhei.ttf")), 30);
//            cs.setFont(PDType1Font.TIMES_ROMAN, 30);
            // 旋转的角度,用弧度表示;水平移动300;纵向移动200
            cs.setTextMatrix(Matrix.getRotateInstance(0.6,300f,200f));
            cs.showText(ts);
            cs.endText();

            cs.close();
        }
        doc.save(targetPDF);
    }
}

结果:

文件体积:

利用IText

<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itextpdf</artifactId>
    <version>5.5.13.1</version>
</dependency>

<dependency>
    <groupId>com.itextpdf</groupId>
    <artifactId>itext-asian</artifactId>
    <version>5.2.0</version>
</dependency>
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Element;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;

import java.io.FileInputStream;
import java.io.FileOutputStream;

public class PDFWaterMark {

    public static void main(String[] args) throws Exception {
        useIText();
    }

    private static void useIText() throws Exception {
        // 水印文字
        String ts = "给PDF加水印";

        FileInputStream sourcePDF = new FileInputStream("20210331165837838.pdf");
        FileOutputStream targetPDF = new FileOutputStream("20210331165837838-watermark-itext.pdf");

        PdfReader reader = new PdfReader(sourcePDF);
        PdfStamper stamp = new PdfStamper(reader, targetPDF);

        // 用自定义字体
        BaseFont font = BaseFont.createFont("华康少女文字简W5.ttc,1", BaseFont.IDENTITY_H, true);

        // 源PDF文件的总页数
        int pageSize = reader.getNumberOfPages();
        for (int i = 1; i <= pageSize; i++) {
            // 水印在之前文本下
            PdfContentByte under = stamp.getUnderContent(i);
            under.beginText();
            // 颜色 RGBA
            under.setColorFill(new BaseColor(197f,0f,35f,50));
            // 字体
            under.setFontAndSize(font, 38);
            // under.setTextMatrix(300, 200);
            // 文字居中;水印文字;X坐标;Y坐标;旋转角度
            under.showTextAligned(Element.ALIGN_CENTER, ts, 300, 200, 45);
            under.endText();
        }
        stamp.close();
    }
}

结果

 文件体积:

IText比PDFBox要好,即使引入外部字体文件,最终生成的PDF体积没有明显变化

扩展,关于颜色

 

参考:https://www.colormatters.com/color-and-design/color-systems-rgb-and-cmyk

印刷颜色选择:https://htmlcolors.com/

CMYK配色表:http://www.wahart.com.hk/cmyk.htm

小LUA 面对敌人的严刑逼供,我一个字也没说,而是一五一十写了下来。
原文地址:https://www.cnblogs.com/LUA123/p/14633622.html