【spire-free添加水印】

使用spire-free添加各类文件类型水印

依赖:

 <dependencies>
        <dependency>
            <groupId>e-iceblue</groupId>
            <artifactId>spire.office.free</artifactId>
            <version>5.3.1</version>
        </dependency>
        <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>
    </dependencies>
    <repositories>
        <repository>
            <id>com.e-iceblue</id>
            <name>e-iceblue</name>
            <url>https://repo.e-iceblue.com/nexus/content/groups/public/</url>
        </repository>
    </repositories>

工具方法:


import com.spire.doc.*;
import com.spire.doc.FileFormat;
import com.spire.pdf.*;
import com.spire.pdf.PdfPageBase;
import com.spire.presentation.Presentation;
import com.spire.presentation.SlideBackground;
import com.spire.presentation.collections.SlideCollection;
import com.spire.presentation.drawing.BackgroundType;
import com.spire.presentation.drawing.FillFormatType;
import com.spire.presentation.drawing.IImageData;
import com.spire.presentation.drawing.PictureFillType;
import com.spire.xls.Workbook;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.Dimension2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;

/**
 * @author shorey
 * @date 2022年4月14日
 */
@Slf4j
@Component
public class WaterMarkUtils {


    /**
     * 目前可支持加水印的文件类型
     */
    private static final List<String> FILE_TYPE_LIST = Arrays.asList(".jpg", ".jpeg", ".png", ".bmp", ".JPG", ".PNG", ".JPEG", ".BMP", ".docx", ".xlsx", ".pptx", ".doc", ".xls", ".ppt", ".pdf");

    private static final String PDF = ".pdf";
    private static final String DOC = ".doc.docx";
    private static final String XLS = ".xls.xlsx";
    private static final String PPT = ".ppt.pptx";
    private static final String IMG = ".jpg.JPG.png.PNG.jpeg.JPEG.bmp.BMP";

    public static InputStream addWaterMark(InputStream inputStream, String fileName, String waterMark) throws Exception {
        log.info("添加水印文件:{}", fileName);
        log.info("水印内容:{}", waterMark);
        //获取文件后缀
        String suffix = fileName.substring((fileName.lastIndexOf(".") + 1));
        if (!FILE_TYPE_LIST.contains("." + suffix)) {
            return inputStream;
        }

        if (PDF.contains(suffix)) {
            return pdfAddWaterMark(inputStream, waterMark, fileName);
        }
        if (DOC.contains(suffix)) {
            return wordAddWaterMark(inputStream, waterMark, fileName);
        }
        if (XLS.contains(suffix)) {
            return xlsAddWaterMark(inputStream, waterMark, fileName);
        }
        if (PPT.contains(suffix)) {
            return pptAddWaterMark(inputStream, waterMark, fileName);
        }
        if (IMG.contains(suffix)) {
            return imageAddWaterMark(inputStream, waterMark, suffix, fileName);
        }
        return null;
    }

    /**
     * @param inputStream
     * @throws Exception
     */
    public static InputStream pdfAddWaterMark(InputStream inputStream, String waterMark, String fileName) throws Exception {
        //创建PdfDocument对象
        PdfDocument pdf = new PdfDocument();
        //加载示例文档
        pdf.loadFromStream(inputStream);
        double height = pdf.getPages().get(0).getActualSize().getHeight();
        double width = pdf.getPages().get(0).getActualSize().getWidth();
        BufferedImage bufferedImage = ImageIO.read(new ByteArrayInputStream(createWaterMark(waterMark, (int) width, (int) height).toByteArray()));
        //获取第一页
        //遍历文档每一页,加载图片,并设置成平铺背景(水印)
        for (int i = 0; i < pdf.getPages().getCount(); i++) {
            PdfPageBase page = pdf.getPages().get(i);
            //设置背景图片
            page.setBackgroundImage(bufferedImage);
        }

        //输出
        ByteArrayOutputStream dstStream = new ByteArrayOutputStream();
        pdf.saveToStream(dstStream, com.spire.pdf.FileFormat.PDF);
        byte[] bytes = dstStream.toByteArray();
        InputStream byteStream = new ByteArrayInputStream(bytes);
        dstStream.close();
        System.out.println("PDF水印添加完成!");

        return byteStream;

    }

    public static InputStream wordAddWaterMark(InputStream inputStream, String waterMark, String fileName) throws IOException, FontFormatException {
        Document document = new Document();
        document.loadFromStream(inputStream, FileFormat.Auto);
        double height = document.getSections().get(0).getPageSetup().getPageSize().getHeight();
        double width = document.getSections().get(0).getPageSetup().getPageSize().getWidth();
        //加载需要设置成水印的图片
        PictureWatermark picture = new PictureWatermark();
        picture.setPicture(new ByteArrayInputStream(createWaterMark(waterMark, (int) width, (int) height).toByteArray()));
//        picture.setScaling(20);
        picture.isWashout(false);
        //将图片设置成水印
        document.setWatermark(picture);
        //保存文档
        ByteArrayOutputStream dstStream = new ByteArrayOutputStream();
        document.saveToStream(dstStream, FileFormat.Auto);
        byte[] bytes = dstStream.toByteArray();
        InputStream byteStream = new ByteArrayInputStream(bytes);
        dstStream.close();
        System.out.println("WORD水印添加完成!");
        return byteStream;
    }

    public static InputStream pptAddWaterMark(InputStream inputStream, String waterMark, String fileName) throws Exception {
        Presentation presentation = new Presentation();
        presentation.loadFromStream(inputStream, com.spire.presentation.FileFormat.AUTO);
        Dimension2D size = presentation.getSlideSize().getSize();
        int height = (int) size.getHeight();
        int width = (int) size.getWidth();
        //获取水印图片
        IImageData image = presentation.getImages().append(ImageIO.read(new ByteArrayInputStream(createWaterMark(waterMark, width, height).toByteArray())));

        //获取幻灯片背景属性,设置图片填充
        SlideCollection slides = presentation.getSlides();
        for (int i = 0; i < slides.getCount(); i++) {
            SlideBackground background = presentation.getSlides().get(i).getSlideBackground();
            background.setType(BackgroundType.CUSTOM);
            background.getFill().setFillType(FillFormatType.PICTURE);
            background.getFill().getPictureFill().setFillType(PictureFillType.TILE);
            background.getFill().getPictureFill().getPicture().setEmbedImage(image);
        }
        //保存文档
        ByteArrayOutputStream dstStream = new ByteArrayOutputStream();
        presentation.saveToFile(dstStream, com.spire.presentation.FileFormat.AUTO);
        byte[] bytes = dstStream.toByteArray();
        InputStream byteStream = new ByteArrayInputStream(bytes);
        dstStream.close();
        System.out.println("PPT水印添加完成!");
        return byteStream;

    }

    public static InputStream xlsAddWaterMark(InputStream inputStream, String waterMark, String fileName) throws Exception {
        Workbook workbook = new Workbook();
        workbook.loadFromStream(inputStream);

        int count = workbook.getWorksheets().getCount();
        int width = 180;
        int height = 90;
        for (int i = 0; i < count; i++) {
            width = (int) workbook.getWorksheets().get(i).getPageSetup().getPageWidth();
            height = (int) workbook.getWorksheets().get(i).getPageSetup().getPageHeight();

            workbook.getWorksheets().get(i).getPageSetup().setBackgoundImage(ImageIO.read(new ByteArrayInputStream(createWaterMark(waterMark, width, height).toByteArray())));
            workbook.getWorksheets().get(i).getPageSetup().setLeftHeader("&G");

        }
        ByteArrayOutputStream dstStream = new ByteArrayOutputStream();
        workbook.saveToStream(dstStream);
        byte[] bytes = dstStream.toByteArray();
        InputStream byteStream = new ByteArrayInputStream(bytes);
        dstStream.close();
        System.out.println("EXCEL水印添加完成!");
        return byteStream;
    }

    public static InputStream imageAddWaterMark(InputStream inputStream, String waterMark, String suffix, String fileName) throws Exception {
        String[] contents = waterMark.split(",");
        Image image = ImageIO.read(inputStream);

        int width = image.getWidth(null);
        int height = image.getHeight(null);
        BufferedImage bufImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

        String fontType = "FangSong";
        int fontStyle = Font.BOLD;
        int fontSize = 11;
        Font font = new Font(fontType, fontStyle, fontSize);
        font = font.deriveFont(15f);
        log.info("============================font:" + font.toString() + "=================================");
        Graphics2D g2d = bufImg.createGraphics(); // 获取Graphics2d对象
        g2d.drawImage(image, 0, 0, width, height, null);
        g2d.setColor(new Color(65, 177, 221, 147));
        g2d.setFont(font);
        //设置倾斜度
        g2d.rotate(-0.5, (double) bufImg.getWidth() / 2, (double) bufImg.getHeight() / 2);
        // 获取其中最长的文字水印的大小
        int maxLen = 0;
        int maxHigh = 0;
        for (int i = 0; i < contents.length; i++) {
            waterMark = contents[i];
            int fontlen = getWatermarkLength(waterMark, g2d);
            if (fontlen >= maxLen) {
                maxLen = fontlen;
            }
            maxHigh = maxHigh + (i + 1) * fontSize + 10;
        }
        // 文字长度相对于图片宽度应该有多少行
        int line = width * 2 / maxLen;
        int co = height * 2 / maxHigh;

        int yz = 0;
        // 填充Y轴方向
        for (int a = 0; a < co; a++) {
            int t = 0;
            for (int j = 0; j < contents.length; j++) {
                waterMark = contents[j];
                int y = (j + 1) * fontSize + 10 + t;

                // 文字叠加,自动换行叠加,注意符号
                int tempX = -width / 2;
                int tempY = -height / 2 + y + yz;
                // 单字符长度
                int tempCharLen = 0;
                // 单行字符总长度临时计算
                int tempLineLen = 0;
                StringBuffer sb = new StringBuffer();
                for (int i = 0; i < waterMark.length(); i++) {
                    char tempChar = waterMark.charAt(i);
                    tempCharLen = getCharLen(tempChar, g2d);
                    tempLineLen += tempCharLen;

                    // 和图片的长度进行对应的比较操作
                    if (tempLineLen >= width) {
                        // 长度已经满一行,进行文字叠加
                        g2d.drawString(sb.toString(), tempX, tempY);
                        t = t + fontSize;
                        // 清空内容,重新追加
                        sb.delete(0, sb.length());
                        tempY += fontSize;
                        tempLineLen = 0;
                    }
                    // 追加字符
                    sb.append(tempChar);
                }
                // 填充X轴
                for (int z = 0; z < line; z++) {
                    // 最后叠加余下的文字
                    g2d.drawString(sb.toString(), tempX, tempY);
                    tempX = tempX + maxLen + XMOVE;
                }
            }
            yz = yz + maxHigh + YMOVE;
        }
        g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
        // 释放对象
        g2d.dispose();
        ByteArrayOutputStream dstStream = new ByteArrayOutputStream();
        ImageIO.write(bufImg, suffix, dstStream);
        byte[] bytes = dstStream.toByteArray();
        InputStream byteStream = new ByteArrayInputStream(bytes);
        dstStream.close();
        System.out.println("IMG水印添加完成!");
        return byteStream;
    }

    /**
     * 水印之间的横向间隔
     */
    private static final int XMOVE = 80;

    /**
     * 水印之间的纵向间隔
     */
    private static final int YMOVE = 80;

    public static ByteArrayOutputStream createWaterMark(String content, int width, int height) throws IOException, FontFormatException {
        String[] contents = content.split(",");
        // 获取bufferedImage对象
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        String fontType = "FangSong";
        int fontStyle = Font.BOLD;
        int fontSize = 11;
        Font font = new Font(fontType, fontStyle, fontSize);
        font = font.deriveFont(15f);
        log.info("============================font:" + font.toString() + "=================================");
        Graphics2D g2d = image.createGraphics(); // 获取Graphics2d对象
        image = g2d.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT);
        g2d.dispose();
        g2d = image.createGraphics();
        //设置字体颜色和透明度,最后一个参数为透明度
        g2d.setColor(new Color(65, 177, 221, 147));
        // 设置字体
        g2d.setStroke(new BasicStroke(1));
        // 设置字体类型  加粗 大小
        g2d.setFont(font);
        //设置倾斜度
        g2d.rotate(-0.5, (double) image.getWidth() / 2, (double) image.getHeight() / 2);
        // 获取其中最长的文字水印的大小
        int maxLen = 0;
        int maxHigh = 0;
        for (int i = 0; i < contents.length; i++) {
            content = contents[i];
            int fontlen = getWatermarkLength(content, g2d);
            if (fontlen >= maxLen) {
                maxLen = fontlen;
            }
            maxHigh = maxHigh + (i + 1) * fontSize + 10;
        }
        // 文字长度相对于图片宽度应该有多少行
        int line = width * 2 / maxLen;
        int co = height * 2 / maxHigh;

        int yz = 0;
        // 填充Y轴方向
        for (int a = 0; a < co; a++) {
            int t = 0;
            for (int j = 0; j < contents.length; j++) {
                content = contents[j];
                int y = (j + 1) * fontSize + 10 + t;

                // 文字叠加,自动换行叠加,注意符号
                int tempX = -width / 2;
                int tempY = -height / 2 + y + yz;
                // 单字符长度
                int tempCharLen = 0;
                // 单行字符总长度临时计算
                int tempLineLen = 0;
                StringBuffer sb = new StringBuffer();
                for (int i = 0; i < content.length(); i++) {
                    char tempChar = content.charAt(i);
                    tempCharLen = getCharLen(tempChar, g2d);
                    tempLineLen += tempCharLen;

                    // 和图片的长度进行对应的比较操作
                    if (tempLineLen >= width) {
                        // 长度已经满一行,进行文字叠加
                        g2d.drawString(sb.toString(), tempX, tempY);
                        t = t + fontSize;
                        // 清空内容,重新追加
                        sb.delete(0, sb.length());
                        tempY += fontSize;
                        tempLineLen = 0;
                    }
                    // 追加字符
                    sb.append(tempChar);
                }
                // 填充X轴
                for (int z = 0; z < line; z++) {
                    // 最后叠加余下的文字
                    g2d.drawString(sb.toString(), tempX, tempY);
                    tempX = tempX + maxLen + XMOVE;
                }
            }
            yz = yz + maxHigh + YMOVE;
        }
        // 设置透明度
        g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
        // 释放对象
        g2d.dispose();
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        ImageIO.write(image, "png", os);
        return os;
    }

    public static int getCharLen(char c, Graphics2D g) {
        return g.getFontMetrics(g.getFont()).charWidth(c);
    }

    /**
     * 获取水印文字总长度
     *
     * @paramwaterMarkContent水印的文字
     * @paramg
     * @return水印文字总长度
     */
    public static int getWatermarkLength(String waterMarkContent, Graphics2D g) {
        return g.getFontMetrics(g.getFont()).charsWidth(waterMarkContent.toCharArray(), 0, waterMarkContent.length());
    }
}

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Free Spire.PDF for .NET 是 Spire.PDF for .NET 的免费版本,无需购买即可用于个人或商业用途。使用该组件,程序员可以 在.NET 程序中创建、读取、写入、编辑和操作 PDF 文档。这个控件能支持的功能十分全面,例如文档安全性设置(电子签名),提取 PDF 文本、附件、图片,PDF 合并和拆分,更新 Metadata,设置 Section,绘制图形、插入图片、表格制作和加工、导入数据等等。除此以外,Spire.PDF 还可以将 TXT 文本、图片、HTML 高质量地转换为 PDF 文件格式。 主要功能如下: 1.高质量的文档转换。Free Spire.PDF for .NET 支持 PDF 到 Word、XPS、SVG、EMF、Text 和图片(EMF、JPG、PNG、BMP、TIFF)的格式转换。也支持从 XML、HTML、RTF、XPS、Text、图片等格式生成 PDF 文档。 2.文档操作及域功能。支持合并、拆分 PDF 文档,在原有的 PDF 文档页添加覆盖页。同时,Spire.PDF 提供导入、邮戳、小册子功能,以及帮助用户从数据库读取数据并填充到域的域填写功能。 3. 安全性设置。用户可以通过设置密码和数字签名来保护 PDF 文档。用户密码和所有者密码可以确定加密的 PDF 文档的可读性、可修改性、是否可打印等有选择性的限制。与此同时,数字签名作为一个更有效的方法,可以应用于维护和对PDF文档进行身份验证。 4.数据提取。支持快速高效地从 PDF 文档提取图片、文本、PDF 分页,以及附件。 5.文件属性设置。支持对 Metadata、文件属性、页面方向、页面大小进行设置。其中文件属性包括文件限制(打印、页面提取、加评论等方面的权限限制)以及文件描述属性(文件名称、作者、主题、关键字等)。使用 Spire.PDF for .NET,用户还可以根据自己阅读喜好设定默认打开页码,分页模式,缩放比例和打印缩放,等等。 6.其他功能。 支持多种语言,支持字体格式、对齐方式设置。 绘制文字,图片,图形。 支持添加图层,透明图像,Color Space,条形码到 PDF。 支持 PDF/A-1b、PDF/x1a:2001 格式。 添加梯状图形和矢量图像到指定位置。 添加并格式化表格。 插入交互元素,例如添加自定义的 Annotation、Action、JavaScript、附件、书签等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值