java实现隐形水印pdf (java如何添加pdf水印)

背景介绍

在实际的项目当中,有很多这样的场景,管理后台上传word模板文件(如协议、合同、通知书等),需要通过代码实现,将业务数据写入到word文件的不同位置,然后生成pdf文件并上传到文件服务器,提供用户*载下**或者预览的功能。比如:用户在某平台借款,生成的借款协议。

java如何添加pdf水印,word转pdf文件中如何插入水印

插件*载下**与安装

本文主要使用 Aspose.Words 实现word转pdf,通过替换word中的占位符实现文件中数据的更新。更多功能可以参考Aspose官方网站。

  • 插件*载下**

链接:https://pan.baidu.com/s/1TbkczJNSN9X8LjV5L49ssw

提取码:vspw

官网*载下**地址: https://www.aspose.com/

  • 插件安装

*载下**的jar包,可以直接放到java项目当中,也可以上传到maven*服私**追加pom引用。

效果展示

  • 原word文件,有year、month、day、user_name四个占位符

java如何添加pdf水印,word转pdf文件中如何插入水印

  • 转换后的PDF文件,占位符信息已更新,并追加了水印

java如何添加pdf水印,word转pdf文件中如何插入水印

代码逻辑

import com.aspose.words.Shape;
import com.aspose.words.*;

import java.awt.*;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author luandy
 * @create 2021/02/28 12:43
 */
public class TestWordsToPdf {
    /** isMatchCase 是否区分大小写 */
    private static final boolean IS_MATCH_CASE_TRUE = true;
    /** isMatchWholeWord 是否全词匹配 */
    private static final boolean IS_MATCH_WHOLE_WORD_TRUE = false;

    /** 字体目录:mac系统,根据系统字体目录调整 */
    private static final String FONT_FOLDER = "/System/Library/Fonts";

    /**
     * 测试方法
     *
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        String wordPath = "/Users/luandy/Downloads/模板_V1.0.docx";
        String pdfPath = "/Users/luandy/Downloads/模板_V1.0." + System.currentTimeMillis() + ".pdf";

        ConcurrentHashMap<String, String> dataMap = new ConcurrentHashMap();
        dataMap.put("year", "2021");
        dataMap.put("month", "2");
        dataMap.put("day", "28");
        dataMap.put("user_name", "我是八零后琐话,欢迎您的关注");

        // word转换pdf
        docToPdf(wordPath, pdfPath, dataMap);
    }

    /**
     * word转pdf主方法
     * 
     * @param wordPath
     * @param pdfPath
     * @param dataMap
     * @return
     * @throws Exception
     */
    public static boolean docToPdf(String wordPath, String pdfPath, ConcurrentHashMap<String, String> dataMap) throws Exception {
        // 验证License 若不验证则转化出的pdf文档会有水印产生
        if (!isWordLicense()) {
            System.out.println("License验证不通过...");
            return false;
        }
        File pdfFile = null;
        FileOutputStream pdfFos = null;
        try {
            long old = System.currentTimeMillis();
            // 新建一个pdf文档
            pdfFile = new File(pdfPath);
            pdfFos = new FileOutputStream(pdfFile);
            // 将要被转化的word文档
            Document doc = new Document(wordPath);
            // 字体设置
            FontSettings.setFontsFolder(FONT_FOLDER + File.separator, true);
            // Aspose.Words 使用Replace()对模板进行替换字符操作
            replaceWordsKey(doc, dataMap);
            // 为PDF追加水印
            insertWaterMarkText(doc, "八零后琐话");
            // 全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF, EPUB, XPS, SWF 相互转换
            doc.save(pdfFos, SaveFormat.PDF);
            long now = System.currentTimeMillis();
            System.out.println("共耗时:" + ((now - old) / 1000.0) + "秒");
        } catch (Exception e) {
            System.out.println("Word 转 Pdf 失败..." + e);
            // 为了不生成空文件,出现异常时,删除pdf文件,以便重新生成
            if (pdfFile != null) {
                pdfFile.delete();
            }
            return false;
        } finally {
            if (pdfFos != null) {
                pdfFos.close();
            }
        }
        // 文件转换成功
        return true;
    }

    /**
     * 替换Word中的占位符
     *
     * @param doc
     * @param dataMap
     * @throws Exception
     */
    private static void replaceWordsKey(Document doc, ConcurrentHashMap<String, String> dataMap) throws Exception {
        for (Map.Entry<String, String> entry : dataMap.entrySet()) {
            // 替换Word中的变量,longfor_year为word模板中的占位符,2021为替换的数据,isMatchCase 是否区分大小写,isMatchWholeWord 是否全词匹配
            doc.getRange().replace(entry.getKey(), entry.getValue(), IS_MATCH_CASE_TRUE, IS_MATCH_WHOLE_WORD_TRUE);
        }
    }

    /**
     * 验证aspose.word组件是否授权:无授权的文件有水印和试用标记
     *
     * @return
     */
    private static boolean isWordLicense() {
        try {
            // 避免文件遗漏
            String licensexml = "<License>\n" + "<Data>\n" + "<Products>\n"
                    + "<Product>Aspose.Total for Java</Product>\n" + "<Product>Aspose.Words for Java</Product>\n"
                    + "</Products>\n" + "<EditionType>Enterprise</EditionType>\n"
                    + "<SubscriptionExpiry>20991231</SubscriptionExpiry>\n"
                    + "<LicenseExpiry>20991231</LicenseExpiry>\n"
                    + "<SerialNumber>23dcc79f-44ec-4a23-be3a-03c1632404e9</SerialNumber>\n" + "</Data>\n"
                    + "<Signature>\n"
                    + "sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU=\n"
                    + "</Signature>\n" + "</License>";
            InputStream inputStream = new ByteArrayInputStream(licensexml.getBytes());
            com.aspose.words.License license = new com.aspose.words.License();
            license.setLicense(inputStream);
        } catch (Exception e) {
            System.out.println("License验证异常..." + e);
            return false;
        }
        return true;
    }

    /**
     * 为PDF添加水印
     *
     * @param doc
     * @param waterMarkText
     * @throws Exception
     */
    private static void insertWaterMarkText(Document doc, String waterMarkText) throws Exception {
        Shape watermark = new Shape(doc, ShapeType.TEXT_PLAIN_TEXT);
        // 水印内容
        watermark.getTextPath().setText(waterMarkText);
        // 水印字体
        watermark.getTextPath().setFontFamily("宋体");
        // 水印宽度
        watermark.setWidth(600);
        // 水印高度
        watermark.setHeight(150);
        // 旋转水印
        watermark.setRotation(-60);
        // 水印颜色
        watermark.getFill().setColor(Color.lightGray);
        watermark.setStrokeColor(Color.lightGray);
        watermark.setRelativeHorizontalPosition(RelativeHorizontalPosition.PAGE);
        watermark.setRelativeVerticalPosition(RelativeVerticalPosition.PAGE);
        watermark.setWrapType(WrapType.NONE);
        watermark.setVerticalAlignment(VerticalAlignment.CENTER);
        watermark.setHorizontalAlignment(HorizontalAlignment.CENTER);
        Paragraph watermarkPara = new Paragraph(doc);
        watermarkPara.appendChild(watermark);
        for (Section sect : doc.getSections()) {
            insertWaterMarkIntoHeader(watermarkPara, sect, HeaderFooterType.HEADER_PRIMARY);
            insertWaterMarkIntoHeader(watermarkPara, sect, HeaderFooterType.HEADER_FIRST);
            insertWaterMarkIntoHeader(watermarkPara, sect, HeaderFooterType.HEADER_EVEN);
        }
    }

    private static void insertWaterMarkIntoHeader(Paragraph waterMarkPara, Section sect, int headerType) throws Exception {
        HeaderFooter header = sect.getHeadersFooters().getByHeaderFooterType(headerType);
        if (header == null) {
            header = new HeaderFooter(sect.getDocument(), headerType);
            sect.getHeadersFooters().add(header);
        }
        header.appendChild(waterMarkPara.deepClone(true));
    }
}

java如何添加pdf水印,word转pdf文件中如何插入水印