java使用spire实现对图片、pdf、doc、xsl、ppt添加水印

  1. 引入依赖
        <!--
            在阅读或编写Word文件时,Free Spire.Office for Java限制为500段和25个表格。将Word文件转换为其他文件格式时,只能获得生成文件的前3页。

            在读取或写入.xls文件时,Free Spire.Office for Java的每个工作簿限制为5张,每张工作簿限制为200行,而.xlsx文件格式则没有此限制。将Excel转换为其他文件格式时,只能获得生成文件的前3页。

            在阅读或撰写PDF和PowerPoint文件时,Free Spire.Office for Java限制为10页。将PDF和PowerPoint文件转换为其他文件格式时,只能获得生成文件的前3页。

            生成或扫描条形码时,Free Spire.Office for Java仅支持有限数量的条形码类型。
        -->
        <dependency>
            <groupId>e-iceblue</groupId>
            <artifactId>spire.office.free</artifactId>
            <version>5.3.1</version>
        </dependency>

    <repositories>
          <repository>
            <id>com.e-iceblue</id>
            <url>https://repo.e-iceblue.cn/repository/maven-public/</url>
        </repository>
    </repositories>

2、工具类

import com.spire.doc.*;
import com.spire.doc.documents.Paragraph;
import com.spire.doc.documents.ShapeLineStyle;
import com.spire.doc.documents.ShapeType;
import com.spire.doc.documents.WatermarkLayout;
import com.spire.doc.fields.ShapeObject;
import com.spire.pdf.PdfDocument;
import com.spire.pdf.PdfPageBase;
import com.spire.pdf.graphics.*;
import com.spire.presentation.IAutoShape;
import com.spire.presentation.PortionEx;
import com.spire.presentation.Presentation;
import com.spire.presentation.drawing.FillFormatType;
import com.spire.xls.ViewMode;
import com.spire.xls.Worksheet;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.Dimension2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.*;

/**
 *  java使用spire实现对图片、pdf、doc、xsl、ppt添加水印
 */
public class WaterMarkUtils1 {

    /**
     * 缓存区路径
     */
    private static String OUT_PATH = "C:\\Users\\issuser\\Desktop\\水印\\";
    //水印文字颜色
    private static Color COLOR = Color.LIGHT_GRAY;
    //背景颜色
    private static Color BACK_COLOR = Color.white;
    //水印透明度
    private static float ALPHA = 0.5f;
    //旋转角度
    private static Integer DEGREE = -45;
    //字号大小
    private static int FONT_SIZE = 30;
    //水印文字字体
    private static Font FONT = new Font("仿宋", Font.BOLD, FONT_SIZE);

    private static final Logger logger = LoggerFactory.getLogger(WaterMarkUtils1.class);

    /**
     * 读取缓存区的文件
     *
     * @param path 文件路径
     */
    private static MultipartFile fileToMultipart(String path) {
        File file = new File(path);
        //无参构造,文件大小最大值便是默认值10kb,超过10Kb便会通过生成临时文件转化不占用内存
        FileItemFactory factory = new DiskFileItemFactory();
        FileItem item = factory.createItem("textField", "text/plain", true, file.getName());
        int bytesRead;
        byte[] buffer = new byte[path.length()];
        try (FileInputStream fis = new FileInputStream(file);
             OutputStream os = item.getOutputStream()) {
            while ((bytesRead = fis.read(buffer, 0, path.length())) != -1) {
                os.write(buffer, 0, bytesRead);
            }
        } catch (IOException e) {
            logger.info("文件转化失败, fileUrl: " + file.getName());
            logger.info("e: " + e);
            return null;
        } finally {
            //操作完删除缓存区文件
            //file.delete();
        }
        return new CommonsMultipartFile(item);
    }

    //============================================1、图片添加动态文字水印==================================================

    /**
     * 图片添加文字水印
     *
     * @param logoText 水印文字
     * @param srcFile  原图片文件
     */
    public static MultipartFile setWaterMarkToImageByWords(MultipartFile srcFile, String logoText) {
        InputStream is = null;
        OutputStream os = null;
        try {
            // 1、源图片
            InputStream inputImg = srcFile.getInputStream();
            BufferedImage srcImg = ImageIO.read(inputImg);
            //原图宽
            int imgWidth = srcImg.getWidth();
            //原图高
            int imgHeight = srcImg.getHeight();
            BufferedImage buffImg = new BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_INT_RGB);
            // 2、得到画笔对象
            Graphics2D g = buffImg.createGraphics();
            // 3、设置样式
            //消除对线段锯齿
            g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            //消除画图锯齿
            g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            //消除文字锯齿
            g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
            g.drawImage(srcImg, 0, 0, srcImg.getWidth(null), srcImg.getHeight(null), null);
            //文字水印的宽
            JLabel label = new JLabel(logoText);
            FontMetrics metrics = label.getFontMetrics(FONT);
            int width = metrics.stringWidth(label.getText());

            //TODO 特别注意:图片原点(0,0)在左上角
            //向左旋转45°,则第一个水印在左下角比较美观
            //横向打水印,以文字水印的宽为间隔
            for (int i = 0; i <= imgWidth; i += width) {
                //纵向打水印,以文字水印的宽为间隔
                for (int j = imgHeight; j >= 0; j -= width) {
                    // 得到画笔对象,基于图片对象打开绘图
                    g = (Graphics2D) buffImg.getGraphics();
                    //4、设置水印文字颜色
                    g.setColor(COLOR);
                    //5、设置水印文字Font
                    g.setFont(FONT);
                    //6、设置水印文字透明度
                    g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, ALPHA));
                    //7、设置水印旋转,一定要设置x,y值,否则会有偏移(度数,X,Y)
                    g.rotate(Math.toRadians(DEGREE), i, j);
                    //8、绘制文字,第一参数->设置的内容,后面两个参数->文字在图片上的坐标位置(x,y)
                    g.drawString(logoText, i, j);
                }
            }

            // 9、释放资源
            g.dispose();

            // 获取图片文件名 xxx.png xxx
            String originFileName = srcFile.getOriginalFilename();
            // 获取原图片后缀 png
            int lastSplit = originFileName.lastIndexOf(".");
            String suffix = originFileName.substring(lastSplit + 1);

            //10、输出新图片
            OutputStream bs = new FileOutputStream(OUT_PATH + srcFile.getOriginalFilename());
            ImageOutputStream imOut = ImageIO.createImageOutputStream(bs);
            ImageIO.write(buffImg, suffix, imOut);
            // 加水印后的文件上传
            srcFile = fileToMultipart(OUT_PATH + srcFile.getOriginalFilename());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != is)
                    is.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                if (null != os)
                    os.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return srcFile;
    }

    public static ByteArrayOutputStream setWaterMarkToImageByWords(InputStream is,String logoText,String fileName) {
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        try {
            // 1、源图片
            BufferedImage srcImg = ImageIO.read(is);
            //原图宽
            int imgWidth = srcImg.getWidth();
            //原图高
            int imgHeight = srcImg.getHeight();
            BufferedImage buffImg = new BufferedImage(imgWidth, imgHeight, BufferedImage.TYPE_INT_RGB);
            // 2、得到画笔对象
            Graphics2D g = buffImg.createGraphics();
            // 3、设置样式
            //消除对线段锯齿
            g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            //消除画图锯齿
            g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            //消除文字锯齿
            g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
            g.drawImage(srcImg, 0, 0, srcImg.getWidth(null), srcImg.getHeight(null), null);
            //文字水印的宽
            JLabel label = new JLabel(logoText);
            FontMetrics metrics = label.getFontMetrics(FONT);
            int width = metrics.stringWidth(label.getText());

            //TODO 特别注意:图片原点(0,0)在左上角
            //向左旋转45°,则第一个水印在左下角比较美观
            //横向打水印,以文字水印的宽为间隔
            for (int i = 0; i <= imgWidth; i += width) {
                //纵向打水印,以文字水印的宽为间隔
                for (int j = imgHeight; j >= 0; j -= width) {
                    // 得到画笔对象,基于图片对象打开绘图
                    g = (Graphics2D) buffImg.getGraphics();
                    //4、设置水印文字颜色
                    g.setColor(COLOR);
                    //5、设置水印文字Font
                    g.setFont(FONT);
                    //6、设置水印文字透明度
                    g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, ALPHA));
                    //7、设置水印旋转,一定要设置x,y值,否则会有偏移(度数,X,Y)
                    g.rotate(Math.toRadians(DEGREE), i, j);
                    //8、绘制文字,第一参数->设置的内容,后面两个参数->文字在图片上的坐标位置(x,y)
                    g.drawString(logoText, i, j);
                }
            }

            // 9、释放资源
            g.dispose();
            //文件类型
            String srcImageType = fileName.substring(fileName.lastIndexOf(".") + 1);
            //10、输出新图片
            ImageIO.write(buffImg, srcImageType, os);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            IOStreamUtils.closeStream(is);
            //IOStreamUtils.closeStream(os);
        }
        return os;
    }

    //============================================2、PDF添加动态文字水印==================================================

    /**
     * PDF添加文字水印
     *
     * @param srcPdf   上传文件
     * @param logoText 水印文字
     */
    public static MultipartFile setWaterMarkToPdfByWords(MultipartFile srcPdf, String logoText) {
        try {
            InputStream inputStream = srcPdf.getInputStream();
            PdfDocument pdf = new PdfDocument();
            //加载示例文档
            pdf.loadFromStream(inputStream);
            //true防止中文乱码
            PdfTrueTypeFont pdfTrueTypeFont = new PdfTrueTypeFont(new Font("仿宋", Font.BOLD, 25), true);
            for (Object obj : pdf.getPages()) {
                //当前页
                PdfPageBase page = (PdfPageBase) obj;
                double width = page.getCanvas().getClientSize().getWidth();
                double height = page.getCanvas().getClientSize().getHeight();
                //1、当前页进行区域划分,当前页纵向3列,横向3行,共9个区域
                Dimension2D dimension2D = new Dimension();
                dimension2D.setSize(width / 3, height / 3);
                //2、对区域画水印
                PdfTilingBrush brush = new PdfTilingBrush(dimension2D);
                //透明度
                brush.getGraphics().setTransparency(ALPHA);
                //旋转角度
                brush.getGraphics().rotateTransform(DEGREE);
                //设置区域水印位置,垂直水平居中
                double offsetX = 0;
                double offsetY = brush.getSize().getHeight() / 2;
                brush.getGraphics().translateTransform(offsetX, offsetY);
                //画水印,居中展示:文本、字体、颜色、x、y、居中展示
                brush.getGraphics().drawString(logoText, pdfTrueTypeFont, PdfBrushes.getLightGray(), 0, 0, new PdfStringFormat(PdfTextAlignment.Center));
                //恢复
                brush.getGraphics().restore();
                //保存格式
                brush.getGraphics().save();
                //3、根据当前页大小,创建新画布
                Rectangle2D loRect = new Rectangle2D.Float();
                loRect.setFrame(new Point2D.Float(0, 0), page.getCanvas().getClientSize());
                //4、将新画布和水印画入当前页
                page.getCanvas().drawRectangle(brush, loRect);
            }
            //设置缓存区
            pdf.saveToFile(OUT_PATH + srcPdf.getOriginalFilename());
            pdf.close();
            //读取缓存区的文件
            srcPdf = fileToMultipart(OUT_PATH + srcPdf.getOriginalFilename());
        } catch (Exception e) {
            logger.info("pdf添加水印异常: " + e);
            e.printStackTrace();
        }
        return srcPdf;
    }

    public static ByteArrayOutputStream setWaterMarkToPdfByWords(InputStream is,String logoText) {
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        try {
            PdfDocument pdf = new PdfDocument();
            //加载示例文档
            pdf.loadFromStream(is);
            //true防止中文乱码
            PdfTrueTypeFont pdfTrueTypeFont = new PdfTrueTypeFont(new Font("仿宋", Font.BOLD, 25), true);
            for (Object obj : pdf.getPages()) {
                //当前页
                PdfPageBase page = (PdfPageBase) obj;
                double width = page.getCanvas().getClientSize().getWidth();
                double height = page.getCanvas().getClientSize().getHeight();
                //1、当前页进行区域划分,当前页纵向3列,横向3行,共9个区域
                Dimension2D dimension2D = new Dimension();
                dimension2D.setSize(width / 3, height / 3);
                //2、对区域画水印
                PdfTilingBrush brush = new PdfTilingBrush(dimension2D);
                //透明度
                brush.getGraphics().setTransparency(ALPHA);
                //旋转角度
                brush.getGraphics().rotateTransform(DEGREE);
                //设置区域水印位置,垂直水平居中
                double offsetX = 0;
                double offsetY = brush.getSize().getHeight() / 2;
                brush.getGraphics().translateTransform(offsetX, offsetY);
                //画水印,居中展示:文本、字体、颜色、x、y、居中展示
                brush.getGraphics().drawString(logoText, pdfTrueTypeFont, PdfBrushes.getLightGray(), 0, 0, new PdfStringFormat(PdfTextAlignment.Center));
                //恢复
                brush.getGraphics().restore();
                //保存格式
                brush.getGraphics().save();
                //3、根据当前页大小,创建新画布
                Rectangle2D loRect = new Rectangle2D.Float();
                loRect.setFrame(new Point2D.Float(0, 0), page.getCanvas().getClientSize());
                //4、将新画布和水印画入当前页
                page.getCanvas().drawRectangle(brush, loRect);
            }
            //设置缓存区
            pdf.saveToStream(os, com.spire.pdf.FileFormat.PDF);
            pdf.close();
        } catch (Exception e) {
            logger.info("pdf添加水印异常: " + e);
            e.printStackTrace();
        } finally {
            IOStreamUtils.closeStream(is);
            //IOStreamUtils.closeStream(os);
        }
        return os;
    }

    //============================================3、DOCX/DOC添加文字水印==================================================

    /**
     * DOCX/DOC添加文字水印-单个水印
     *
     * @param srcPdf   上传文件
     * @param logoText 水印文字
     */
    public static MultipartFile setWaterMarkToDocByWords01(MultipartFile srcPdf, String logoText) {
        try {
            InputStream inputStream = srcPdf.getInputStream();
            Document doc = new Document();
            doc.loadFromStream(inputStream, FileFormat.Auto);
            //创建TextWatermark实例
            TextWatermark txtWatermark = new TextWatermark();
            //设置文本水印格式
            txtWatermark.setText(logoText);
            //字体
            txtWatermark.setFontName("仿宋");
            //字号
            txtWatermark.setFontSize(FONT_SIZE);
            //颜色
            txtWatermark.setColor(COLOR);
            //文字倾斜角度 此处使用斜对角
            txtWatermark.setLayout(WatermarkLayout.Diagonal);
            //半透明
            txtWatermark.setSemitransparent(true);

            //获取第一节
            Section section = doc.getSections().get(0);
            //将文本水印添加到示例文档
            section.getDocument().setWatermark(txtWatermark);
            //保存文档
            doc.saveToFile(OUT_PATH + srcPdf.getOriginalFilename());
            //读取缓存区的文件
            srcPdf = fileToMultipart(OUT_PATH + srcPdf.getOriginalFilename());

        } catch (Exception e) {
            logger.info("doc添加水印异常: " + e);
            e.printStackTrace();
        }
        return srcPdf;
    }

    /**
     * DOCX/DOC添加文字水印-多行水印
     *
     * @param srcPdf   上传文件
     * @param logoText 水印文字
     */
    public static MultipartFile setWaterMarkToDocByWords02(MultipartFile srcPdf, String logoText) {
        try {
            InputStream inputStream = srcPdf.getInputStream();
            Document doc = new Document();
            doc.loadFromStream(inputStream, FileFormat.Auto);
            //添加艺术字并设置大小
            ShapeObject shape = new ShapeObject(doc, ShapeType.Text_Plain_Text);
            shape.setWidth(150);
            shape.setHeight(20);
            //旋转角度
            shape.setRotation(315);
            //shape.setRotation(Math.toRadians(DEGREE));
            //字体名称
            shape.getWordArt().setFontFamily("仿宋");
            //文本内容
            shape.getWordArt().setText(logoText);
            //填充颜色
            shape.setFillColor(COLOR);
            //设置线条样式
            shape.setLineStyle(ShapeLineStyle.Single);
            //设置笔划颜色
            shape.setStrokeColor(COLOR);
            //设置笔划权重
            shape.setStrokeWeight(1);

            Section section;
            HeaderFooter header;
            for (int n = 0; n < doc.getSections().getCount(); n++) {
                section = doc.getSections().get(n);
                //获取section的页眉
                header = section.getHeadersFooters().getHeader();
                Paragraph paragraph;
                if (header.getParagraphs().getCount() > 0) {
                    //如果页眉有段落,取它第一个段落
                    paragraph = header.getParagraphs().get(0);
                } else {
                    //否则新增加一个段落到页眉
                    paragraph = header.addParagraph();
                }
                for (int i = 0; i < 3; i++) {
                    for (int j = 0; j < 3; j++) {
                        //复制艺术字并设置多行多列位置
                        shape = (ShapeObject) shape.deepClone();
                        //设置艺术字文本内容、位置及样式
                        shape.setVerticalPosition(150 + 200 * i);
                        shape.setHorizontalPosition(20 + 200 * j);
                        paragraph.getChildObjects().add(shape);
                    }
                }
            }
            //保存文档
            doc.saveToFile(OUT_PATH + srcPdf.getOriginalFilename());
            //读取缓存区的文件
            srcPdf = fileToMultipart(OUT_PATH + srcPdf.getOriginalFilename());

        } catch (Exception e) {
            logger.info("doc添加水印异常: " + e);
            e.printStackTrace();
        }
        return srcPdf;
    }

    public static ByteArrayOutputStream setWaterMarkToDocByWords02(InputStream is,String logoText) {
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        try {
            Document doc = new Document();
            doc.loadFromStream(is, FileFormat.Auto);
            //添加艺术字并设置大小
            ShapeObject shape = new ShapeObject(doc, ShapeType.Text_Plain_Text);
            shape.setWidth(150);
            shape.setHeight(20);
            //旋转角度
            shape.setRotation(315);
            //shape.setRotation(Math.toRadians(DEGREE));
            //字体名称
            shape.getWordArt().setFontFamily("仿宋");
            //文本内容
            shape.getWordArt().setText(logoText);
            //填充颜色
            shape.setFillColor(COLOR);
            //设置线条样式
            shape.setLineStyle(ShapeLineStyle.Single);
            //设置笔划颜色
            shape.setStrokeColor(COLOR);
            //设置笔划权重
            shape.setStrokeWeight(1);

            Section section;
            HeaderFooter header;
            for (int n = 0; n < doc.getSections().getCount(); n++) {
                section = doc.getSections().get(n);
                //获取section的页眉
                header = section.getHeadersFooters().getHeader();
                Paragraph paragraph;
                if (header.getParagraphs().getCount() > 0) {
                    //如果页眉有段落,取它第一个段落
                    paragraph = header.getParagraphs().get(0);
                } else {
                    //否则新增加一个段落到页眉
                    paragraph = header.addParagraph();
                }
                for (int i = 0; i < 3; i++) {
                    for (int j = 0; j < 3; j++) {
                        //复制艺术字并设置多行多列位置
                        shape = (ShapeObject) shape.deepClone();
                        //设置艺术字文本内容、位置及样式
                        shape.setVerticalPosition(150 + 200 * i);
                        shape.setHorizontalPosition(20 + 200 * j);
                        paragraph.getChildObjects().add(shape);
                    }
                }
            }
            //保存文档
            doc.saveToStream(os,FileFormat.Auto);
        } catch (Exception e) {
            logger.info("doc添加水印异常: " + e);
            e.printStackTrace();
        } finally {
            IOStreamUtils.closeStream(is);
            //IOStreamUtils.closeStream(os);
        }
        return os;
    }

    //============================================4、XLS/XLSL添加文字水印==================================================

    /**
     * XLSX添加文字水印
     *
     * @param srcFile  上传文件
     * @param logoText 水印文字
     */
    public static MultipartFile setWaterMarkToXlsxByWords(MultipartFile srcFile, String logoText) {
        try {
            com.spire.xls.Workbook wb = new com.spire.xls.Workbook();
            InputStream inputStream = srcFile.getInputStream();
            wb.loadFromStream(inputStream);
            for (int i = 0; i < wb.getWorksheets().getCount(); i++) {
                //当前sheet页
                Worksheet sheet = wb.getWorksheets().get(i);
                //工作簿高
                double height = sheet.getPageSetup().getPageHeight();
                //工作簿宽
                double width = sheet.getPageSetup().getPageWidth();
                //调用DrawText() 方法插入图片
                BufferedImage imgWtrmrk = drawText(logoText, height, width);
                //将图片设置为页眉
                sheet.getPageSetup().setCenterHeaderImage(imgWtrmrk);
                sheet.getPageSetup().setCenterHeader("&G");
                //将显示模式设置为Layout
                sheet.setViewMode(ViewMode.Layout);
            }
            //保存文档
            wb.saveToFile(OUT_PATH + srcFile.getOriginalFilename());
            //读取缓存区的文件
            srcFile = fileToMultipart(OUT_PATH + srcFile.getOriginalFilename());
        } catch (Exception e) {
            logger.info("xlsx添加水印异常: " + e);
        }
        return srcFile;
    }

    public static ByteArrayOutputStream setWaterMarkToXlsxByWords(InputStream is,String logoText) {
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        try {
            com.spire.xls.Workbook wb = new com.spire.xls.Workbook();
            wb.loadFromStream(is);
            for (int i = 0; i < wb.getWorksheets().getCount(); i++) {
                //当前sheet页
                Worksheet sheet = wb.getWorksheets().get(i);
                //工作簿高
                double height = sheet.getPageSetup().getPageHeight();
                //工作簿宽
                double width = sheet.getPageSetup().getPageWidth();
                //调用DrawText() 方法插入图片
                BufferedImage imgWtrmrk = drawText(logoText, height, width);
                //将图片设置为页眉
                sheet.getPageSetup().setCenterHeaderImage(imgWtrmrk);
                sheet.getPageSetup().setCenterHeader("&G");
                //将显示模式设置为Layout
                sheet.setViewMode(ViewMode.Layout);
            }
            //保存文档
            wb.saveToStream(os);
        } catch (Exception e) {
            logger.info("xlsx添加水印异常: " + e);
        } finally {
            IOStreamUtils.closeStream(is);
            //IOStreamUtils.closeStream(os);
        }
        return os;
    }

    /**
     * 绘制图片
     *
     * @param text   水印文字
     * @param height 工作簿高
     * @param width  工作簿宽
     * @return
     */
    private static BufferedImage drawText(String text, double height, double width) {
        //水印文本
        text += "   " + text;
        //定义图片宽度和高度
        BufferedImage img = new BufferedImage((int) width, (int) height, BufferedImage.TYPE_INT_ARGB);
        //创建画笔
        Graphics2D loGraphic = img.createGraphics();
        //获取文本size
        FontMetrics loFontMetrics = loGraphic.getFontMetrics(FONT);
        //文字宽
        int liStrWidth = loFontMetrics.stringWidth(text);
        //文字高
        int liStrHeight = loFontMetrics.getHeight();
        //水印背景颜色
        loGraphic.setColor(BACK_COLOR);
        //绘制矩形
        loGraphic.fillRect(0, 0, (int) width, (int) height);

        //如果你调用translate(50, 50),则绘图的起点将从(0,0)移动到(50,50)。绘制一个矩形时,坐标(0,0)将对应于新的坐标(50,50)。
        //重新设定原点坐标
        loGraphic.translate(((int) width - liStrWidth) / 2, ((int) height - liStrHeight) / 2);
        //执行图片旋转,rotate里包含了translate,并还原了原点坐标
        loGraphic.rotate(Math.toRadians(DEGREE), liStrWidth / 2, liStrHeight / 2);
        //还原设定原点坐标
        loGraphic.translate(-((int) width - liStrWidth) / 2, -((int) height - liStrHeight) / 2);

        //打3行,分4份
        int row = 3;
        for (int i = row; i > 0; i--) {
            //设置字体
            loGraphic.setFont(FONT);
            //水印字体颜色
            loGraphic.setColor(COLOR);
            //设置水印文字透明度
            loGraphic.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, ALPHA));
            //文本显示样式及位置
            loGraphic.drawString(text, 0, (int) height / 4 * i);
        }
        //关闭画笔
        loGraphic.dispose();
        return img;
    }

    //============================================5、PPT/PPTX添加文字水印==================================================

    /**
     * ppt文件添加水印,实际上只是添加背景图片
     *
     * @param srcFile  上传文件
     * @param logoText 水印文字
     * @return
     */
    public static MultipartFile setWaterMarkToPptxByWords(MultipartFile srcFile,String logoText) {
        try {
            Presentation presentation = new Presentation();
            InputStream inputStream = srcFile.getInputStream();
            presentation.loadFromStream(inputStream,com.spire.presentation.FileFormat.PPTX_2016);
            //设置文本水印的宽和高
            int width = 300;
            int height = 200;
            //水印坐标
            float x = 0;
            float y = 0;
            //给每页PPT打水印
            for (int i = 0; i < presentation.getSlides().size(); i++) {
                //打5行
                for (int j = 0; j < 5; j++) {
                    y = height * j;
                    //打3列
                    for (int k = 0; k < 3; k++) {
                        x = width * k;
                        Rectangle2D.Double rect = new Rectangle2D.Double(x, y, width, height);
                        //添加一个shape到定义区域
                        IAutoShape shape = presentation.getSlides().get(i).getShapes().appendShape(com.spire.presentation.ShapeType.RECTANGLE, rect);
                        //设置shape样式
                        shape.getFill().setFillType(FillFormatType.NONE);
                        shape.getShapeStyle().getLineColor().setColor(Color.WHITE);
                        shape.getShapeStyle().getFillColor().setColor(Color.red);
                        shape.getShapeStyle().getEffectColor().setColor(Color.RED);
                        //旋转角度
                        shape.setRotation(DEGREE);
                        shape.getLocking().setSelectionProtection(true);
                        shape.getLine().setFillType(FillFormatType.NONE);
                        //添加文本到shape
                        shape.getTextFrame().setText(logoText);

                        PortionEx textRange = shape.getTextFrame().getTextRange();
                        //设置文本水印样式
                        textRange.getFill().setFillType(FillFormatType.SOLID);
                        //字体颜色
                        textRange.getFill().getSolidColor().setColor(Color.LIGHT_GRAY);
                        //字体大小
                        textRange.setFontHeight(30);
                    }
                }
            }
            //保存文档
            presentation.saveToFile(OUT_PATH + srcFile.getOriginalFilename(), com.spire.presentation.FileFormat.PPTX_2016);
            //读取缓存区的文件
            srcFile = fileToMultipart(OUT_PATH + srcFile.getOriginalFilename());
        } catch (Exception e) {
            logger.info("ppt添加水印异常: " + e);
        }
        return srcFile;
    }

    public static ByteArrayOutputStream setWaterMarkToPptxByWords(InputStream is, String logoText) {
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        try {
            Presentation presentation = new Presentation();
            presentation.loadFromStream(is,com.spire.presentation.FileFormat.PPTX_2016);
            //如果超过10页,不打水印
            if (presentation.getSlides().size()>10){
                return null;
            }
            //设置文本水印的宽和高
            int width = 300;
            int height = 200;
            //水印坐标
            float x = 0;
            float y = 0;
            //给每页PPT打水印
            for (int i = 0; i < presentation.getSlides().size(); i++) {
                //打5行
                for (int j = 0; j < 5; j++) {
                    y = height * j;
                    //打3列
                    for (int k = 0; k < 3; k++) {
                        x = width * k;
                        Rectangle2D.Double rect = new Rectangle2D.Double(x, y, width, height);
                        //添加一个shape到定义区域
                        IAutoShape shape = presentation.getSlides().get(i).getShapes().appendShape(com.spire.presentation.ShapeType.RECTANGLE, rect);
                        //设置shape样式
                        shape.getFill().setFillType(FillFormatType.NONE);
                        shape.getShapeStyle().getLineColor().setColor(Color.WHITE);
                        shape.getShapeStyle().getFillColor().setColor(Color.red);
                        shape.getShapeStyle().getEffectColor().setColor(Color.RED);
                        //旋转角度
                        shape.setRotation(DEGREE);
                        shape.getLocking().setSelectionProtection(true);
                        shape.getLine().setFillType(FillFormatType.NONE);
                        //添加文本到shape
                        shape.getTextFrame().setText(logoText);

                        PortionEx textRange = shape.getTextFrame().getTextRange();
                        //设置文本水印样式
                        textRange.getFill().setFillType(FillFormatType.SOLID);
                        //字体颜色
                        textRange.getFill().getSolidColor().setColor(Color.LIGHT_GRAY);
                        //字体大小
                        textRange.setFontHeight(30);
                    }
                }
            }
            //保存文档
            presentation.saveToFile(os,com.spire.presentation.FileFormat.PPTX_2016);
        } catch (Exception e) {
            logger.info("ppt添加水印异常: " + e);
        } finally {
            IOStreamUtils.closeStream(is);
            //IOStreamUtils.closeStream(os);
        }
        return os;
    }


}
  1. 测试
 public static void main(String[] args) throws IOException {
        //水印文字
        String logoText = "习大大:155****5886";
        //原文件地址
        String inPath = "";
        //原文件
        MultipartFile srcFile = null;
        //1、测试图片打水印
        /*inPath = "C:\\Users\\issuser\\Desktop\\文件\\test01.jpg";
        srcFile = WaterMarkUtils1.fileToMultipart(inPath);
        WaterMarkUtils1.setWaterMarkToImageByWords(srcFile, logoText);*/

        //2、测试PDF打水印
        /*inPath = "C:\\Users\\issuser\\Desktop\\文件\\yyh-test.pdf";
        srcFile = WaterMarkUtils1.fileToMultipart(inPath);
        WaterMarkUtils1.setWaterMarkToPdfByWords(srcFile, logoText);*/

        //3、测试Word打水印
        /*inPath = "C:\\Users\\issuser\\Desktop\\文件\\test.docx";
        srcFile = WaterMarkUtils1.fileToMultipart(inPath);
        WaterMarkUtils1.setWaterMarkToDocByWords02(srcFile, logoText);*/

        //4、测试Excel打水印
        /*inPath = "C:\\Users\\issuser\\Desktop\\文件\\test.xlsx";
        srcFile = WaterMarkUtils1.fileToMultipart(inPath);
        ByteArrayOutputStream bytes = WaterMarkUtils1.setWaterMarkToXlsxByWords(srcFile.getInputStream(), logoText);
        OutputStream os = new FileOutputStream(OUT_PATH+"test.xlsx");
        os.write(bytes.toByteArray());*/

        //5、测试PPT打水印
        inPath = "C:\\Users\\issuser\\Desktop\\文件\\test.pptx";
        InputStream is = new FileInputStream(new File(inPath));
        //srcFile = WaterMarkUtils1.fileToMultipart(inPath);
        ByteArrayOutputStream bytes = WaterMarkUtils1.setWaterMarkToPptxByWords(is, logoText);
        OutputStream os = new FileOutputStream(OUT_PATH+"test.pptx");
        os.write(bytes.toByteArray());

    }
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,546评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,224评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,911评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,737评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,753评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,598评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,338评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,249评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,696评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,888评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,013评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,731评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,348评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,929评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,048评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,203评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,960评论 2 355

推荐阅读更多精彩内容