实现office word,excel,ppt,pdf,图片上传文档加水印

1.maven依赖


            org.apache.poi
            poi
            3.16
        
        
            org.apache.poi
            poi-ooxml
            3.16
        
        
            com.itextpdf
            itext-asian
            5.2.0
        
        
            org.apache.pdfbox
            pdfbox
            2.0.18
        
        
            com.itextpdf
            itextpdf
            5.5.13.1
        
        
        
            org.springframework
            spring-mock
            2.0.8
        

2.工具类


import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.pdf.*;
import com.microsoft.schemas.office.office.CTLock;
import com.microsoft.schemas.vml.*;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageDecoder;
import org.apache.poi.hslf.usermodel.HSLFPictureShape;
import org.apache.poi.hslf.usermodel.HSLFSlide;
import org.apache.poi.hslf.usermodel.HSLFSlideShow;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.hwpf.usermodel.Range;
import org.apache.poi.sl.usermodel.PictureData;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.wp.usermodel.HeaderFooterType;
import org.apache.poi.xslf.usermodel.XMLSlideShow;
import org.apache.poi.xslf.usermodel.XSLFPictureShape;
import org.apache.poi.xslf.usermodel.XSLFSlide;
import org.apache.poi.xssf.usermodel.XSSFRelation;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFHeader;
import org.apache.xmlbeans.XmlObject;
import org.openxmlformats.schemas.presentationml.x2006.main.CTSlide;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.Color;
import java.awt.Font;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.stream.Stream;

/**
 * @author: dumin3
 * @date: 2020/9/9 15:22
 * @description:
 */
public class WaterMarkUtils {

    // word字体
    private static final String fontName = "宋体";
    // 字体大小
    private static final String fontSize = "0.2pt";
    // 字体颜色
    private static final String fontColor = "#d0d0d0";
    // 一个字平均长度,单位pt,用于:计算文本占用的长度(文本总个数*单字长度)
    private static  final Integer widthPerWord = 10;
    // 与顶部的间距
    private static Integer styleTop = 0;
    // 文本旋转角度
    private static final String styleRotation = "45";

    /**
     * @param file:
     * @param markText:
     * @param type:
     * @return: org.springframework.web.multipart.MultipartFile
     * @author: dumin3
     * @date: 2020/9/9 16:48
     * @description: word文档类型判断后添加水印
     */
    public static MultipartFile setWordWaterMark(MultipartFile file,String markText,String type){
        if (type.equals("docx")){
            try {
                XWPFDocument doc = new XWPFDocument(file.getInputStream());
                waterMarkDocXDocument(doc,markText);
                ByteArrayOutputStream baos = new ByteArrayOutputStream();//二进制OutputStream
                doc.write(baos);//文档写入流
                ByteArrayInputStream in = new ByteArrayInputStream(baos.toByteArray());//OutputStream写入InputStream二进制流
                MultipartFile multipartFile = new MockMultipartFile(file.getName(),file.getOriginalFilename(),"", in);
                return multipartFile;
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else if (type.equals("doc")){
            try {
                HWPFDocument doc1 = new HWPFDocument(file.getInputStream());
                Range range = doc1.getRange();
                return file;
               /* OfficeDrawings officeDrawing = doc1.getOfficeDrawingsMain();
                officeDrawing.
                XWPFDocument doc = new XWPFDocument(file.getInputStream());
                waterMarkDocXDocument(doc,markText);
                ByteArrayOutputStream baos = new ByteArrayOutputStream();//二进制OutputStream
                doc.write(baos);//文档写入流
                ByteArrayInputStream in = new ByteArrayInputStream(baos.toByteArray());//OutputStream写入InputStream二进制流
                MultipartFile multipartFile = new MockMultipartFile(file.getName(),file.getOriginalFilename(),"", in);
                return multipartFile;*/
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else if (type.equals("jpg")||type.equals("jpeg")||type.equals("png")){
            return markImageByText(file,markText,45);
        } else if (type.equals("xlsx")||type.equals("xls")) {
            return setExcelWaterMark(file, markText,type);
        } else if (type.equals("pptx")||type.equals("ppt")){
            return setPPTWaterMark(file,markText,type);
        } else if (type.equals("pdf")){
            return setPDFWatermark(file,markText);
        }
        return file;
    }


    /**********************************---------------------docx添加水印----------------------**********************************/

    /**
     * 给文档添加水印
     * 此方法可以单独使用
     * @param doc
     * @param customText
     */
    public static void waterMarkDocXDocument(XWPFDocument doc,String customText){
        // 把整页都打上水印
        for (int lineIndex = -5; lineIndex < 20; lineIndex++) {
            styleTop = 100*lineIndex;
            waterMarkDocXDocument_0(doc,customText);
        }
    }



    /**
     * 为文档添加水印
     * @param doc 需要被处理的docx文档对象
     * @param customText 需要添加的水印文字
     */
    public static void waterMarkDocXDocument_0(XWPFDocument doc,String customText) {
        // 水印文字之间使用8个空格分隔
        customText = customText + repeatString(" ", 8);
        // 一行水印重复水印文字次数
        customText = repeatString(customText, 10);
        // 如果之前已经创建过 DEFAULT 的Header,将会复用
        XWPFHeader header = doc.createHeader(HeaderFooterType.DEFAULT);
        int size = header.getParagraphs().size();
        if (size == 0) {
            header.createParagraph();
        }
        CTP ctp = header.getParagraphArray(0).getCTP();
        byte[] rsidr = doc.getDocument().getBody().getPArray(0).getRsidR();
        byte[] rsidrdefault = doc.getDocument().getBody().getPArray(0).getRsidRDefault();
        ctp.setRsidP(rsidr);
        ctp.setRsidRDefault(rsidrdefault);
        CTPPr ppr = ctp.addNewPPr();
        ppr.addNewPStyle().setVal("Header");
        // 开始加水印
        CTR ctr = ctp.addNewR();
        CTRPr ctrpr = ctr.addNewRPr();
        ctrpr.addNewNoProof();
        CTGroup group = CTGroup.Factory.newInstance();
        CTShapetype shapetype = group.addNewShapetype();
        CTTextPath shapeTypeTextPath = shapetype.addNewTextpath();
        shapeTypeTextPath.setOn(STTrueFalse.T);
        shapeTypeTextPath.setFitshape(STTrueFalse.T);
        CTLock lock = shapetype.addNewLock();
        lock.setExt(STExt.VIEW);
        CTShape shape = group.addNewShape();
        shape.setId("PowerPlusWaterMarkObject");
        shape.setSpid("_x0000_s102");
        shape.setType("#_x0000_t136");
        // 设置形状样式(旋转,位置,相对路径等参数)
        shape.setStyle(getShapeStyle(customText));
        shape.setFillcolor(fontColor);
        // 字体设置为实心
        shape.setStroked(STTrueFalse.FALSE);
        // 绘制文本的路径
        CTTextPath shapeTextPath = shape.addNewTextpath();
        // 设置文本字体与大小
        shapeTextPath.setStyle("font-family:" + fontName + ";font-size:" + fontSize);
        shapeTextPath.setString(customText);
        CTPicture pict = ctr.addNewPict();
        pict.set(group);
    }



    /**
     * 构建Shape的样式参数
     * @param customText
     * @return
     */
    private static String getShapeStyle(String customText) {
        StringBuilder sb = new StringBuilder();
        // 文本path绘制的定位方式
        sb.append("position: ").append("absolute");
        // 计算文本占用的长度(文本总个数*单字长度)
        sb.append(";width: ").append(customText.length() * widthPerWord).append("pt");
        // 字体高度
        sb.append(";height: ").append("20pt");
        sb.append(";z-index: ").append("-251654144");
        sb.append(";mso-wrap-edited: ").append("f");
        // 设置水印的间隔,这是一个大坑,不能用top,必须要margin-top。
        sb.append(";margin-top: ").append(styleTop);
        sb.append(";mso-position-horizontal-relative: ").append("page");
        sb.append(";mso-position-vertical-relative: ").append("page");
        sb.append(";mso-position-vertical: ").append("left");
        sb.append(";mso-position-horizontal: ").append("center");
        sb.append(";rotation: ").append(styleRotation);
        return sb.toString();
    }

    /**
     * 将指定的字符串重复repeats次.
     */
    private static String repeatString(String pattern, int repeats) {
        StringBuilder buffer = new StringBuilder(pattern.length() * repeats);
        Stream.generate(() -> pattern).limit(repeats).forEach(buffer::append);
        return new String(buffer);
    }

    /**
     * MultipartFile 转 File
     *
     * @param file
     * @throws Exception
     */
    public static File multipartFileToFile(MultipartFile file) throws Exception {

        File toFile = null;
        if (file.equals("") || file.getSize() <= 0) {
            file = null;
        } else {
            InputStream ins = null;
            ins = file.getInputStream();
            toFile = new File(file.getOriginalFilename());
            inputStreamToFile(ins, toFile);
            ins.close();
        }
        return toFile;
    }

    //获取流文件
    private static void inputStreamToFile(InputStream ins, File file) {
        try {
            OutputStream os = new FileOutputStream(file);
            int bytesRead = 0;
            byte[] buffer = new byte[8192];
            while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            ins.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }



    /**********************************---------------------图片添加水印----------------------**********************************/

    // 水印透明度
    private static float alpha = 0.5f;
    // 水印横向位置
    private static int positionWidth = 0;
    // 水印纵向位置
    private static int positionHeight = 300;
    // 水印文字字体
    private static Font font = new Font("宋体", Font.BOLD, 32);
    // 水印文字颜色
    private static Color color = Color.gray;

    /**
     *
     * @param alpha
     *            水印透明度
     * @param positionWidth
     *            水印横向位置
     * @param positionHeight
     *            水印纵向位置
     * @param font
     *            水印文字字体
     * @param color
     *            水印文字颜色
     */
    public static void setImageMarkOptions(float alpha, int positionWidth,
                                           int positionHeight, Font font, Color color) {
        if (alpha != 0.0f)
            WaterMarkUtils.alpha = alpha;
        if (positionWidth != 0)
            WaterMarkUtils.positionWidth = positionWidth;
        if (positionHeight != 0)
            WaterMarkUtils.positionHeight = positionHeight;
        if (font != null)
            WaterMarkUtils.font = font;
        if (color != null)
            WaterMarkUtils.color = color;
    }

    /**
     * 给图片添加水印文字、可设置水印文字的旋转角度
     *
     * @param logoText
     * @param multipartFile
     * @param degree
     */
    public static MultipartFile markImageByText(MultipartFile multipartFile, String logoText,Integer degree) {

        InputStream is = null;
        OutputStream os = null;
        try {
            // 1、源图片
            JPEGImageDecoder decoderFile = JPEGCodec.createJPEGDecoder(multipartFile.getInputStream());
            BufferedImage buffImg = decoderFile.decodeAsBufferedImage();
            //Image可以获得 输入图片的信息
            int width = buffImg.getWidth(null);
            int height = buffImg.getHeight(null);


            // 2、得到画笔对象
            Graphics2D g = buffImg.createGraphics();
            // 3、设置对线段的锯齿状边缘处理
            g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                    RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            g.drawImage(
                    buffImg.getScaledInstance(buffImg.getWidth(null),
                            buffImg.getHeight(null), buffImg.SCALE_SMOOTH), 0, 0,
                    null);
            // 4、设置水印旋转
            if (null != degree) {
                g.rotate(Math.toRadians(degree),
                        (double) buffImg.getWidth() / 2,
                        (double) buffImg.getHeight() / 2);
            }
            // 5、设置水印文字颜色
            g.setColor(color);
            // 6、设置水印文字Font
            g.setFont(font);
            // 7、设置水印文字透明度
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,
                    alpha));
            // 8、第一参数->设置的内容,后面两个参数->文字在图片上的坐标位置(x,y)
            for(int i=0;i<9;i++){
                for(int j = 0;j<6;j++){
                    g.drawString(logoText, (int) (width - (width*j/3)), (int) (height - (height*i/5)));
                }
            }

            // 9、释放资源
            g.dispose();
            // 10、生成图片
            InputStream in = bufferedImageToInputStream(buffImg);
            MultipartFile file = new MockMultipartFile(multipartFile.getName(),multipartFile.getOriginalFilename(),"", in);
            System.out.println("图片完成添加水印文字");
            return file;

        } 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 null;
    }


    /**********************************---------------------Excel添加水印----------------------**********************************/

    /**
     * 将BufferedImage转换为InputStream
     * @param image
     * @return
     */
    public static InputStream bufferedImageToInputStream(BufferedImage image){
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        try {
            ImageIO.write(image, "png", os);
            InputStream input = new ByteArrayInputStream(os.toByteArray());
            return input;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 为Excel打上水印工具函数 请自行确保参数值,以保证水印图片之间不会覆盖。 在计算水印的位置的时候,并没有考虑到单元格合并的情况,请注意
     *
     * @param wb
     *            Excel Workbook
     * @param sheet
     *            需要打水印的Excel
     * @param bufferImg
     *            水印地址,classPath,目前只支持png格式的图片,
     *            因为非png格式的图片打到Excel上后可能会有图片变红的问题,且不容易做出透明效果。
     *            同时请注意传入的地址格式,应该为类似:"\\excelTemplate\\test.png"
     * @param startXCol
     *            水印起始列
     * @param startYRow
     *            水印起始行
     * @param betweenXCol
     *            水印横向之间间隔多少列
     * @param betweenYRow
     *            水印纵向之间间隔多少行
     * @param XCount
     *            横向共有水印多少个
     * @param YCount
     *            纵向共有水印多少个
     * @param waterRemarkWidth
     *            水印图片宽度为多少列
     * @param waterRemarkHeight
     *            水印图片高度为多少行
     * @throws IOException
     */
    public static void putWaterRemarkToExcel(Workbook wb, Sheet sheet,BufferedImage bufferImg, int startXCol,
                                             int startYRow, int betweenXCol, int betweenYRow, int XCount, int YCount, int waterRemarkWidth,
                                             int waterRemarkHeight) throws IOException {

        // 导出到字节流B
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        ImageIO.write(bufferImg, "png", os);
        // 加载图片
        // 开始打水印
        Drawing drawing = sheet.createDrawingPatriarch();

        // 按照共需打印多少行水印进行循环
        for (int yCount = 0; yCount < YCount; yCount++) {
            // 按照每行需要打印多少个水印进行循环
            for (int xCount = 0; xCount < XCount; xCount++) {
                // 创建水印图片位置
                int xIndexInteger = startXCol + (xCount * waterRemarkWidth) + (xCount * betweenXCol);
                int yIndexInteger = startYRow + (yCount * waterRemarkHeight) + (yCount * betweenYRow);
                /*
                 * 参数定义: 第一个参数是(x轴的开始节点); 第二个参数是(是y轴的开始节点); 第三个参数是(是x轴的结束节点);
                 * 第四个参数是(是y轴的结束节点); 第五个参数是(是从Excel的第几列开始插入图片,从0开始计数);
                 * 第六个参数是(是从excel的第几行开始插入图片,从0开始计数); 第七个参数是(图片宽度,共多少列);
                 * 第8个参数是(图片高度,共多少行);
                 */
                ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, xIndexInteger,
                        yIndexInteger, xIndexInteger + waterRemarkWidth, yIndexInteger + waterRemarkHeight);

                Picture pic = drawing.createPicture(anchor,
                        wb.addPicture(os.toByteArray(), Workbook.PICTURE_TYPE_PNG));
                pic.resize();
            }
        }
    }


    /**
     * excel设置水印
     * @param file
     * @param markStr
     */
    public static MultipartFile setExcelWaterMark(MultipartFile file, String markStr,String type){
        try {
            FontImage.Watermark watermark = new FontImage.Watermark();
            watermark.setText("水印测试");
            BufferedImage image = FontImage.createWatermarkImage(null);
            if (type.equals("xlsx")) {
                XSSFWorkbook workbook = new XSSFWorkbook(file.getInputStream());

                //获取excel sheet个数
                int sheets = workbook.getNumberOfSheets();
                //循环sheet给每个sheet添加水印
                for (int i = 0; i < sheets; i++) {
                    XSSFSheet sheet = workbook.getSheetAt(i);
                    // 导出到字节流B
                    ByteArrayOutputStream os = new ByteArrayOutputStream();
                    ImageIO.write(image, "png", os);

                    int pictureIdx = workbook.addPicture(os.toByteArray(), Workbook.PICTURE_TYPE_PNG);
                    //add relation from sheet to the picture data
                    String rID = sheet.addRelation(null, XSSFRelation.IMAGES, workbook.getAllPictures().get(pictureIdx)).getRelationship().getId();
                    //set background picture to sheet
                    sheet.getCTWorksheet().addNewPicture().setId(rID);
                }

                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                workbook.write(bos);
                byte[] barray = bos.toByteArray();
                InputStream is = new ByteArrayInputStream(barray);
                MultipartFile multipartFile = new MockMultipartFile(file.getName(), file.getOriginalFilename(), "", is);
                return multipartFile;
            } else {
                HSSFWorkbook wb = new HSSFWorkbook(file.getInputStream());
                //获取excel sheet个数
                int sheets = wb.getNumberOfSheets();
                //循环sheet给每个sheet添加水印
                for (int i = 0; i < sheets; i++) {
                    Sheet sheet = wb.getSheetAt(i);
                    putWaterRemarkToExcel(wb, sheet, image, 0, 0, 6, 10, 10, 10, 0, 0);
                }
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                wb.write(bos);
                byte[] barray = bos.toByteArray();
                InputStream is = new ByteArrayInputStream(barray);
                MultipartFile multipartFile = new MockMultipartFile(file.getName(), file.getOriginalFilename(), "", is);
                return multipartFile;
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    /**********************************---------------------PPT添加水印----------------------**********************************/


    /**
     * @param file:
     * @param markStr:
     * @param fileType:
     * @return: void
     * @author: dumin3
     * @date: 2020/9/10 13:35
     * @description: ppt 添加水印
     */
    public static MultipartFile setPPTWaterMark(MultipartFile file, String markStr, String fileType) {
        try {
            //设置水印图片
            FontImage.Watermark watermark = new FontImage.Watermark();
            watermark.setText("水印测试");
            BufferedImage image = FontImage.createWatermarkImage(null);
            if ("pptx".equals(fileType)) {
                XMLSlideShow slideShow = new XMLSlideShow(file.getInputStream());
                byte[] pictureData = imageToBytes(image);
                PictureData pictureData1 = slideShow.addPicture(pictureData, PictureData.PictureType.PNG);
                for (XSLFSlide slide : slideShow.getSlides()) {
                    for(int i =0 ; i<10;i++) {
                        for(int j = 0;j<8;j++) {
                            XSLFPictureShape pictureShape = slide.createPicture(pictureData1);
                            pictureShape.setAnchor(new java.awt.Rectangle(200 * i, 80 * j, 150, 50));
                        }
                    }
                    CTSlide ctSlide = slide.getXmlObject();
                    XmlObject[] allText = ctSlide.selectPath(
                            "declare namespace a='http://schemas.openxmlformats.org/drawingml/2006/main' " +
                                    ".//a:t"
                    );
                }
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                slideShow.write(bos);
                slideShow.close();
                bos.close();
                byte[] barray = bos.toByteArray();
                InputStream is = new ByteArrayInputStream(barray);
                MultipartFile multipartFile = new MockMultipartFile(file.getName(), file.getOriginalFilename(), "", is);
                return multipartFile;
            } else if ("ppt".equals(fileType)) {
                HSLFSlideShow ppt = new HSLFSlideShow(file.getInputStream());
                byte[] pictureByte = imageToBytes(image);
                PictureData pictureData1 = ppt.addPicture(pictureByte, PictureData.PictureType.PNG);
                for (HSLFSlide slide : ppt.getSlides()) {
                    for(int i =0 ; i<10;i++) {
                        for(int j = 0;j<7;j++) {
                            HSLFPictureShape pictureShape = slide.createPicture(pictureData1);
                            pictureShape.setAnchor(new java.awt.Rectangle(200 * i, 80 * j, 150, 50));
                        }
                    }
                }
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                ppt.write(bos);
                ppt.close();
                bos.close();
                byte[] barray = bos.toByteArray();
                InputStream is = new ByteArrayInputStream(barray);
                MultipartFile multipartFile = new MockMultipartFile(file.getName(), file.getOriginalFilename(), "", is);
                return multipartFile;
            }
        } catch (IOException e){
            e.printStackTrace();
        }
        return null;
    }


    /**
     * BufferedImage转byte[]
     *
     * @param bImage BufferedImage对象
     * @return byte[]
     * @auth zhy
     */
    private static byte[] imageToBytes(BufferedImage bImage) {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        try {
            ImageIO.write(bImage, "png", out);
        } catch (IOException e) {
        }
        return out.toByteArray();
    }

    /**********************************---------------------PDF添加水印----------------------**********************************/

    /**
     *
     * @param file
     *            原PDF文件
     * @param waterMarkName
     *            页脚添加水印
     * @throws DocumentException
     * @throws IOException
     */
    public static MultipartFile setPDFWatermark(MultipartFile file,String waterMarkName) {
        try {

            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            PdfReader reader = new PdfReader(file.getInputStream());
            PdfStamper stamper = new PdfStamper(reader, bos);

            // 获取总页数 +1, 下面从1开始遍历
            int total = reader.getNumberOfPages() + 1;
            // 使用classpath下面的字体库
            BaseFont base = null;
            try {
                base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
            } catch (Exception e) {
                // 日志处理
                e.printStackTrace();
            }

            // 间隔
            int interval = -5;
            // 获取水印文字的高度和宽度
            int textH = 0, textW = 0;
            JLabel label = new JLabel();
            label.setText(waterMarkName);
            FontMetrics metrics = label.getFontMetrics(label.getFont());
            textH = metrics.getHeight();
            textW = metrics.stringWidth(label.getText());
            System.out.println("textH: " + textH);
            System.out.println("textW: " + textW);

            // 设置水印透明度
            PdfGState gs = new PdfGState();
            gs.setFillOpacity(0.2f);
            gs.setStrokeOpacity(0.2f);

            com.itextpdf.text.Rectangle pageSizeWithRotation = null;
            PdfContentByte content = null;
            for (int i = 1; i < total; i++) {
                // 在内容上方加水印
                content = stamper.getOverContent(i);
                // 在内容下方加水印
                // content = stamper.getUnderContent(i);
                content.saveState();
                content.setGState(gs);

                // 设置字体和字体大小
                content.beginText();
                content.setFontAndSize(base, 20);

                // 获取每一页的高度、宽度
                pageSizeWithRotation = reader.getPageSizeWithRotation(i);
                float pageHeight = pageSizeWithRotation.getHeight();
                float pageWidth = pageSizeWithRotation.getWidth();

                // 根据纸张大小多次添加, 水印文字成30度角倾斜
                for (int height = interval + textH; height < pageHeight; height = height + textH * 3) {
                    for (int width = interval + textW; width < pageWidth + textW; width = width + textW * 2) {
                        content.showTextAligned(Element.ALIGN_LEFT, waterMarkName, width - textW, height - textH, 30);
                    }
                }

                content.endText();
            }

            // 关流
            stamper.close();
            reader.close();
            bos.close();
            InputStream is = new ByteArrayInputStream(bos.toByteArray());
            MultipartFile multipartFile = new MockMultipartFile(file.getName(), file.getOriginalFilename(), "", is);
            return multipartFile;
        } catch (DocumentException e){
            e.printStackTrace();
        } catch (IOException e){
            e.printStackTrace();
        }
        return null;
    }

}

package com.fehorizon.hmwf.integration.common.utils;

import com.alibaba.druid.util.StringUtils;
import lombok.Data;

import java.awt.*;
import java.awt.image.BufferedImage;

/**
 * @author: dumin3
 * @date: 2020/9/10 11:03
 * @description:根据文字生成水印图片
 */
public class FontImage {

    @Data
    public static class Watermark {
        private Boolean enable;
        private String text;
        private String dateFormat;
        private String color;
    }

    public static BufferedImage createWatermarkImage(Watermark watermark) {
        if (watermark == null) {
            watermark = new FontImage.Watermark();
            watermark.setEnable(true);
//            watermark.setText("userName");
            watermark.setText("水印测试");
            watermark.setColor("#C5CBCF");
            watermark.setDateFormat("yyyy-MM-dd HH:mm");
        } else {
            if (StringUtils.isEmpty(watermark.getDateFormat())) {
                watermark.setDateFormat("yyyy-MM-dd HH:mm");
            } else if (watermark.getDateFormat().length() == 16) {
                watermark.setDateFormat("yyyy-MM-dd HH:mm");
            } else if (watermark.getDateFormat().length() == 10) {
                watermark.setDateFormat("yyyy-MM-dd");
            }
            if (StringUtils.isEmpty(watermark.getText())) {
                watermark.setText("水印测试");
            }
            if (StringUtils.isEmpty(watermark.getColor())) {
                watermark.setColor("#C5CBCF");
            }
        }
        String[] textArray = watermark.getText().split("\n");
        Font font = new Font("microsoft-yahei", Font.PLAIN, 50);
        Integer width = 200;
        Integer height = 200;

        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        // 背景透明 开始
        Graphics2D g = image.createGraphics();
        image = g.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT);
        g.dispose();
        // 背景透明 结束
        g = image.createGraphics();
        g.setColor(new Color(Integer.parseInt(watermark.getColor().substring(1), 16)));// 设定画笔颜色
        g.setFont(font);// 设置画笔字体
        g.shear(0.1, 0.5);// 设定倾斜度

//        设置字体平滑
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        int y = 50;
        y = y + font.getSize();
//        for (int i = 0; i < textArray.length; i++) {
//            g.drawString(textArray[i], 0, y);// 画出字符串
//            y = y + font.getSize();
//        }
        g.drawString(watermark.getText(), 0, y);// 画出字符串

        g.dispose();// 释放画笔
        return image;

    }

}

你可能感兴趣的:(实现office word,excel,ppt,pdf,图片上传文档加水印)