本文使用jar包pom.xml

<!--水印相关   start--><dependency><groupId>com.itextpdf</groupId><artifactId>itext-asian</artifactId><version>5.2.0</version></dependency><dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.4.3</version></dependency><dependency><groupId>com.lowagie</groupId><artifactId>itext</artifactId><version>2.1.7</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.17</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>3.17</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml-schemas</artifactId><version>3.17</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>ooxml-schemas</artifactId><version>1.0</version></dependency><!-- word --><dependency><groupId>e-iceblue</groupId><artifactId>spire.doc.free</artifactId><version>5.2.0</version></dependency><!-- excel  --><dependency><groupId>e-iceblue</groupId><artifactId>spire.xls.free</artifactId><version>5.1.0</version></dependency><dependency><groupId>e-iceblue</groupId><artifactId>spire.pdf.free</artifactId><version>5.1.0</version></dependency><!-- ppt --><dependency><groupId>e-iceblue</groupId><artifactId>spire.presentation.free</artifactId><version>5.1.0</version></dependency>

office 相关格式文档的加密主要使用微软提供的Spire.Office for Java ,free部分有针对性每个类型的API说明和示例,请自行参考以下链接。下面也会附上我在项目中的实际工具类。

Spire.Office for Java | 专业的 Java Office 套件 | 创建、修改、转换、打印 Word/PowerPoint/PDF 文档

我的策略是读取原文件,加水印后写入新的文件。工具类三个参数依次为原文件路劲、水印文件路径、水印文字内容。下面详细分解。

public static void main(String[] args) throws IOException {String markText = "cq-tengk "+new SimpleDateFormat("yyyy-MM-dd").format(new Date());String oldFile = "D:/tmp/tmp/test.doc";String newFile = "D:/tmp/res/test.doc";addWordWaterMark(oldFile,newFile,markText);
//        setWordWaterMark(oldFile,newFile,markText);
//        addWaterMark(oldFile,newFile,markText);
//        makeWaterMark(oldFile,newFile,markText);}

PDF加水印

/***pdf文件添加文字水印** @param input         原PDF位置* @param output        输出文件的位置* @param waterMarkName 页脚添加水印*/public static void addPDFWaterMark(String input, String output, String waterMarkName) {BufferedOutputStream bos = null;try {bos = new BufferedOutputStream(new FileOutputStream(new File(output)));com.itextpdf.text.pdf.PdfReader reader = new com.itextpdf.text.pdf.PdfReader(input);com.itextpdf.text.pdf.PdfStamper stamper = new com.itextpdf.text.pdf.PdfStamper(reader, bos);// 获取总页数 +1, 下面从1开始遍历int total = reader.getNumberOfPages() + 1;// 使用classpath下面的字体库com.itextpdf.text.pdf.BaseFont base = null;try {base = com.itextpdf.text.pdf.BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", com.itextpdf.text.pdf.BaseFont.EMBEDDED);} catch (Exception e) {// 日志处理e.printStackTrace();}// 间隔int interval = -15;// 获取水印文字的高度和宽度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);// 设置水印透明度com.itextpdf.text.pdf.PdfGState gs = new com.itextpdf.text.pdf.PdfGState();gs.setFillOpacity(0.2f);gs.setStrokeOpacity(0.7f);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 * 6) {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();} catch (FileNotFoundException e) {log.error("PDF加水印失败",e);throw new RuntimeException("PDF makewater fail:生成ppt文件失败");} catch (DocumentException e) {log.error("PDF加水印失败",e);throw new RuntimeException("PDF makewater fail:生成ppt文件失败");} catch (IOException e) {log.error("PDF加水印失败",e);throw new RuntimeException("PDF makewater fail:生成ppt文件失败");}}

Word水印   支持doc和docx

/*** word文字水印** @param inputPath* @param outPath* @param markStr*/public static void addWordWaterMark(String inputPath, String outPath, String markStr) {//加载示例文档Document doc = new Document();doc.loadFromFile(inputPath);//添加艺术字并设置大小ShapeObject shape = new ShapeObject(doc, ShapeType.Text_Plain_Text);shape.setWidth(80);shape.setHeight(20);//设置艺术字文本内容、位置及样式shape.setVerticalPosition(30);shape.setHorizontalPosition(20);shape.setRotation(315);shape.getWordArt().setFontFamily("宋体");shape.getWordArt().setText(markStr);shape.setFillColor(Color.red);shape.setLineStyle(ShapeLineStyle.Single);shape.setStrokeColor(new Color(192, 192, 192, 255));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 < 4; i++) {for (int j = 0; j < 3; j++) {//复制艺术字并设置多行多列位置shape = (ShapeObject) shape.deepClone();shape.setVerticalPosition(50 + 150 * i);shape.setHorizontalPosition(20 + 160 * j);paragraph.getChildObjects().add(shape);}}}//保存文档doc.saveToFile(outPath, FileFormat.Docx_2013);}

Excel     xlsx格式

/*** excel添加水印** @param inputSrc      原始文件路径* @param outputSrc     生成文件路径* @param waterMarkName 水印内容*/private static void addExcelWaterMark(String inputSrc, String outputSrc, String waterMarkName) {byte[] fileData = OfficeWaterMarkUtil.getBytesByFile(inputSrc);BufferedImage image = createWaterMarkImage(waterMarkName);// 导出到字节流BByteArrayOutputStream os = new ByteArrayOutputStream();try {ImageIO.write(image, "png", os);InputStream sbs = new ByteArrayInputStream(fileData);XSSFWorkbook workbook = new XSSFWorkbook(sbs);int pictureIdx = workbook.addPicture(os.toByteArray(), Workbook.PICTURE_TYPE_PNG);POIXMLDocumentPart poixmlDocumentPart = workbook.getAllPictures().get(pictureIdx);for (int i = 0; i < workbook.getNumberOfSheets(); i++) {//获取每个Sheet表XSSFSheet sheet = workbook.getSheetAt(i);PackagePartName ppn = poixmlDocumentPart.getPackagePart().getPartName();String relType = XSSFRelation.IMAGES.getRelation();PackageRelationship pr = sheet.getPackagePart().addRelationship(ppn, TargetMode.INTERNAL, relType, null);sheet.getCTWorksheet().addNewPicture().setId(pr.getId());}ByteArrayOutputStream bos = new ByteArrayOutputStream();try {workbook.write(bos);} finally {bos.close();}bos.writeTo(new BufferedOutputStream(new FileOutputStream(outputSrc)));} catch (IOException e) {log.error("Excel加水印失败",e);throw new RuntimeException("excel makewater fail:生成ppt文件失败");}}

Excel  xls格式

package com.liukuquanshu.thirdparty.util;import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;import javax.imageio.ImageIO;
import java.awt.Color;
import java.awt.Font;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;/*** Excel 加水印工具类   支持xls和xlsx* @author tkai*/
public class ExcelWaterMarkUtil {public static void main(String[] args) {String markText = "cq-tengk "+new SimpleDateFormat("yyyy-MM-dd").format(new Date());String oldFile = "D:/tmp/tmp/数科_软件著作权清单.xls";String newFile = "D:/tmp/res/数科_软件著作权清单.xls";setExcelWaterMark(oldFile,newFile,markText);}/**** @param wb   Excel Workbook* @param sheet  需要打水印的Excel* @param waterRemark  水印文字* @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, String waterRemark, int startXCol,int startYRow, int betweenXCol, int betweenYRow, int XCount, int YCount, int waterRemarkWidth,int waterRemarkHeight) throws IOException {// 加载图片ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();BufferedImage bufferImg = createWaterMarkImage(waterRemark);ImageIO.write(bufferImg, "png", byteArrayOut);// 开始打水印Drawing drawing = sheet.createDrawingPatriarch();Drawing<?> drawingPatriarch = sheet.getDrawingPatriarch();// 按照共需打印多少行水印进行循环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(byteArrayOut.toByteArray(), Workbook.PICTURE_TYPE_PNG));pic.resize();}}}public static void setExcelWaterMark(String inputSrc, String outputSrc, String waterMarkName){try {//读取excel文件Workbook wb =null;if (inputSrc.endsWith("xls")) {wb = new HSSFWorkbook(new FileInputStream(inputSrc));}else if (inputSrc.endsWith("xlsx")){wb = new XSSFWorkbook(new FileInputStream(inputSrc));}//获取excel sheet个数int sheets = wb.getNumberOfSheets();//循环sheet给每个sheet添加水印for (int i = 0; i < sheets; i++) {Sheet sheet = wb.getSheetAt(i);//获取excel实际所占行int row = sheet.getFirstRowNum() + sheet.getLastRowNum();//获取excel实际所占列Row row1 = sheet.getRow(sheet.getFirstRowNum());if (row1==null){continue;}int cell = sheet.getRow(sheet.getFirstRowNum()).getLastCellNum() + 1;//根据行与列计算实际所需多少水印putWaterRemarkToExcel(wb, sheet, waterMarkName, 0, 0, 6, 8, cell / 6 + 1, row / 8 + 1, 0, 0);//设置为受保护sheet.protectSheet(waterMarkName);}ByteArrayOutputStream os = new ByteArrayOutputStream();try {wb.write(os);} catch (IOException e) {e.printStackTrace();}wb.close();byte[] content = os.toByteArray();// Excel文件生成后存储的位置。File file1 = new File(outputSrc);OutputStream fos = null;try {fos = new FileOutputStream(file1);fos.write(content);os.close();fos.close();} catch (Exception e) {e.printStackTrace();}} catch (Exception e) {System.out.println(e.getMessage());}}public static BufferedImage createWaterMarkImage(String waterMark) {String[] textArray = waterMark.split("\n");Font font = new Font("microsoft-yahei", Font.PLAIN, 20);Integer width = 500;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("#C5CBCF".substring(1), 16)));// 设定画笔颜色g.setFont(font);// 设置画笔字体g.shear(0.1, -0.26);// 设定倾斜度// 设置字体平滑g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);int y = 150;for (int i = 0; i < textArray.length; i++) {g.drawString(textArray[i], 0, y);// 画出字符串y = y + font.getSize();}g.dispose();// 释放画笔return image;}}

图片水印   jpg  png 格式

package com.liukuquanshu.thirdparty.util;import lombok.extern.slf4j.Slf4j;import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;/*** Description: 图片水印工具类* @author tengk* @version 1.0*/
@Slf4j
public class ImgWaterMarkUtil {// 水印透明度private static float alpha = 0.7f;// 水印横向位置private static int positionWidth = 150;// 水印纵向位置private static int positionHeight = 300;// 水印文字字体private static Font font = new Font("宋体", Font.BOLD, 20);// 水印文字颜色private static Color color = Color.white;//文字水印位置铺满全屏private static ArrayList position1;private static ArrayList position2;/**** @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) {ImgWaterMarkUtil.alpha = alpha;}if (positionWidth != 0) {ImgWaterMarkUtil.positionWidth = positionWidth;}if (positionHeight != 0) {ImgWaterMarkUtil.positionHeight = positionHeight;}if (font != null) {ImgWaterMarkUtil.font = font;}if (color != null) {ImgWaterMarkUtil.color = color;}}/*** 给图片添加水印图片** @param iconPath*            水印图片路径* @param srcImgPath*            源图片路径* @param targerPath*            目标图片路径*/public static void markImageByIcon(String iconPath, String srcImgPath,String targerPath) {markImageByIcon(iconPath, srcImgPath, targerPath, null);}/*** 给图片添加水印图片、可设置水印图片旋转角度** @param iconPath*            水印图片路径* @param srcImgPath*            源图片路径* @param targerPath*            目标图片路径* @param degree*            水印图片旋转角度*/public static void markImageByIcon(String iconPath, String srcImgPath,String targerPath, Integer degree) {OutputStream os = null;try {Image srcImg = ImageIO.read(new File(srcImgPath));BufferedImage buffImg = new BufferedImage(srcImg.getWidth(null),srcImg.getHeight(null), BufferedImage.TYPE_INT_RGB);// 1、得到画笔对象Graphics2D g = buffImg.createGraphics();// 2、设置对线段的锯齿状边缘处理g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BILINEAR);g.drawImage(srcImg.getScaledInstance(srcImg.getWidth(null),srcImg.getHeight(null), Image.SCALE_SMOOTH), 0, 0,null);// 3、设置水印旋转if (null != degree) {g.rotate(Math.toRadians(degree),(double) buffImg.getWidth() / 2,(double) buffImg.getHeight() / 2);}// 4、水印图片的路径 水印图片一般为gif或者png的,这样可设置透明度ImageIcon imgIcon = new ImageIcon(iconPath);// 5、得到Image对象。Image img = imgIcon.getImage();g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,alpha));// 6、水印图片的位置g.drawImage(img, positionWidth, positionHeight, null);g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));// 7、释放资源g.dispose();// 8、生成图片os = new FileOutputStream(targerPath);ImageIO.write(buffImg, "JPG", os);System.out.println("图片完成添加水印图片");} catch (Exception e) {e.printStackTrace();} finally {try {if(null != os) {os.close();}} catch (Exception e) {e.printStackTrace();}}}/*** 给图片添加水印文字** @param logoText*            水印文字* @param srcImgPath*            源图片路径* @param targerPath*            目标图片路径*/public static void markImageByText(String logoText, String srcImgPath,String targerPath,int allFlag) {markImageByText(logoText, srcImgPath, targerPath, null,allFlag);}/*** 给图片添加水印文字、可设置水印文字的旋转角度** @param logoText* @param srcImgPath* @param targerPath* @param degree*/public static void markImageByText(String logoText, String srcImgPath,String targerPath, Integer degree,int allFlag) {InputStream is = null;OutputStream os = null;try {// 1、源图片Image srcImg = ImageIO.read(new File(srcImgPath));BufferedImage buffImg = new BufferedImage(srcImg.getWidth(null),srcImg.getHeight(null), BufferedImage.TYPE_INT_RGB);// 2、得到画笔对象Graphics2D g = buffImg.createGraphics();// 3、设置对线段的锯齿状边缘处理g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BILINEAR);g.drawImage(srcImg.getScaledInstance(srcImg.getWidth(null),srcImg.getHeight(null), Image.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、设置水印文字Fontg.setFont(font);// 7、设置水印文字透明度g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,alpha));// 8、第一参数->设置的内容,后面两个参数->文字在图片上的坐标位置(x,y)if (allFlag == 1){int width = srcImg.getWidth(null);int height = srcImg.getHeight(null);position1 = new ArrayList();position2 = new ArrayList();position1.add(0);position1.add(width/4);position1.add(width/2);position1.add(width*3/4);position1.add(width);position2.add(0);position2.add(height/4);position2.add(height/2);position2.add(height*3/4);position2.add(height);for (int i = 0; i < position1.size(); i++) {for (int j = 0; j < position2.size(); j++) {g.drawString(logoText,(Integer) position1.get(i),(Integer) position2.get(j));}}}else {g.drawString(logoText,positionWidth,positionHeight);}// 9、释放资源g.dispose();// 10、生成图片os = new FileOutputStream(targerPath);ImageIO.write(buffImg, "JPG", os);System.out.println("图片完成添加水印文字");} catch (Exception e) {log.error("图片加水印失败",e);throw new RuntimeException("图片加水印失败");} finally {try {if (null == is) {} else {is.close();}} catch (Exception e) {e.printStackTrace();}try {if (null != os) {os.close();}} catch (Exception e) {e.printStackTrace();}}}public static void main(String[] args) {String markText = "cq-tengk "+new SimpleDateFormat("yyyy-MM-dd").format(new Date());//图片测试/*String srcImgPath = "D:/tmp/tmp/31.jpg";String targerTextPath2 = "D:/tmp/res/3000.jpg";String targerTextPath = "D:/tmp/tmp/3000.jpg";// 给图片添加水印文字markImageByText(markText, srcImgPath, targerTextPath,0);// 给图片添加水印文字,水印文字旋转-45markImageByText(markText, srcImgPath, targerTextPath2, -45,1);*///文件测试
//        String oldFile = "D:/tmp/tmp/20A00053公开招标(定稿).doc";
//        String newFile = "D:/tmp/res/20A00053公开招标(定稿).doc";
//        String oldFile = "D:/tmp/tmp/5G专网产品资费设计.docx";
//        String newFile = "D:/tmp/res/5G专网产品资费设计.docx";
//        String oldFile = "D:/tmp/tmp/2.xlsx";
//        String newFile = "D:/tmp/res/22.xlsx";String oldFile = "D:/tmp/tmp/2.pdf";String newFile = "D:/tmp/res/22.pdf";
//        String oldFile = "D:/tmp/tmp/2.pptx";
//        String newFile = "D:/tmp/res/2.pptx";OfficeWaterMarkUtil.addWaterMarkOffice(oldFile,newFile,markText);}}

PPTX格式

package com.liukuquanshu.thirdparty.util;import lombok.extern.slf4j.Slf4j;
import org.apache.poi.sl.usermodel.PictureData;
import org.apache.poi.sl.usermodel.PictureData.PictureType;
import org.apache.poi.xslf.usermodel.XMLSlideShow;
import org.apache.poi.xslf.usermodel.XSLFPictureShape;
import org.apache.poi.xslf.usermodel.XSLFSlide;import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;/*** @author tkai* @description: TODO* @date 2022/9/28 17:12*/
@Slf4j
public class PPTWaterMarkUtil {public static void main(String[] args) {String markText = "cq-tengk "+new SimpleDateFormat("yyyy-MM-dd").format(new Date());String oldFile = "D:/tmp/tmp/托尔斯泰.ppt";String newFile = "D:/tmp/res/托尔斯泰.ppt";setPPTWaterMark(oldFile,newFile,markText);}/*** PPT设置水印** @param path* @param targetpath* @param markStr* @throws IOException*/public static void setPPTWaterMark(String path, String targetpath, String markStr) {XMLSlideShow slideShow = null;try {slideShow = new XMLSlideShow(new FileInputStream(path));} catch (IOException e) {log.error("setPPTWaterMark fail:", e);throw new RuntimeException("setPPTWaterMark fail:获取PPT文件失败");}ByteArrayOutputStream os = null;FileOutputStream out = null;try {//获取水印os = getImage(markStr);PictureData pictureData1 = slideShow.addPicture(os.toByteArray(), PictureType.PNG);for (XSLFSlide slide : slideShow.getSlides()) {XSLFPictureShape pictureShape = slide.createPicture(pictureData1);
//                pictureShape.setAnchor(new java.awt.Rectangle(250, 0, 500, 500));pictureShape.setAnchor(pictureShape.getAnchor());}out = new FileOutputStream(targetpath);slideShow.write(out);} catch (IOException e) {log.error("setPPTWaterMark fail:" + e);throw new RuntimeException("setPPTWaterMark fail:生成ppt文件失败");} finally {if (slideShow != null) {try {slideShow.close();} catch (IOException e) {e.printStackTrace();}}if (out != null) {try {out.close();} catch (IOException e) {e.printStackTrace();}}if (os != null) {try {os.close();} catch (IOException e) {e.printStackTrace();}}}}/*** 获取水印文字图片流** @param text* @return*/private static ByteArrayOutputStream getImage(String text) {ByteArrayOutputStream os = new ByteArrayOutputStream();try {// 导出到字节流BBufferedImage image = createWaterMarkImageBig(text);ImageIO.write(image, "png", os);} catch (IOException e) {
//            log.error("getImage fail: 创建水印图片IO异常", e);
//            throw new MyException(ResultCode.FAILURE, "getImage fail: 创建水印图片IO异常");}return os;}/*** 根据文字生成水印图片(大号 平铺)** @param text* @return*/public static BufferedImage createWaterMarkImageBig(String text) {Integer width = 1000;Integer height = 800;BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);// 获取bufferedImage对象Font font = new Font("宋体", Font.PLAIN, 70);Graphics2D g2d = image.createGraphics();image = g2d.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT);g2d.dispose();g2d = image.createGraphics();//设置字体颜色和透明度g2d.setColor(new Color(0, 0, 0, 60));//设置字体g2d.setStroke(new BasicStroke(1));//设置字体类型  加粗 大小g2d.setFont(font);//设置倾斜度g2d.rotate(Math.toRadians(-30), (double) image.getWidth() / 2, (double) image.getHeight() / 2);FontRenderContext context = g2d.getFontRenderContext();Rectangle2D bounds = font.getStringBounds(text, context);double x = (width - bounds.getWidth()) / 2;double y = (height - bounds.getHeight()) / 2;double ascent = -bounds.getY();double baseY = y + ascent;//写入水印文字原定高度过小,所以累计写水印,增加高度g2d.drawString(text, (int) x, (int) baseY);//设置透明度g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));//释放对象g2d.dispose();return image;}}

因为spire free这一套使用有限制,比如ppt只能对十页以内加水印,十页以后的内容会被删去,所以使用了一些别的方法,参考出处因为反复改动记录不详,感谢前面的探索者,这里就不一一列出了。

Java给文件加水印,支持.pptx,.doc,.docx,.xls,.xlsx,.pdf,.png,.jpg。相关推荐

  1. vue - - - - - 在线预览常见文件格式 .doc, .docx, .xls, .xlsx,.pdf

    在线预览常见文件 1.HTML5 - ```embed```标签 1.1 注意⚠️ 1.2 使用方式 2. HTML - ```iframe```标签 2.1 注意⚠️ 2.2 使用方式 3. HTM ...

  2. doc, docx, xls, xlsx, ppt, pptx,txt。等文件转化为pdf

    需要OpenOffice第三插件的支持 ,支持window\linux\mac等系统.doc", "docx", "xls", "xlsx& ...

  3. Java实现文件批量导入导出实例(兼容xls,xlsx)

    <link href="https://csdnimg.cn/public/favicon.ico" rel="SHORTCUT ICON"> &l ...

  4. doc/docx/xls/xlsx 转PDF

    使用语言 python 使用版本 python3 部分文档不能编辑不能解析文档损坏无法处理,运行前需在本地安装Office 参考链接:https://www.cnblogs.com/lzhc/p/10 ...

  5. java office文件加水印_文档预览加水印——或可一用的防泄密方式

    给文件加水印是常见的一种宣示版权的方式.像Office.WPS都自带加水印功能,能够给文档加上"保密"."严禁复制"这样的水印. 在多可系统中,也有这么一个添加 ...

  6. android解析doc,docx,xls,xlsx文件

    导读:有的时候我们在开发android中需要解析一些我们比较常用的格式,比如doc.docx.xls.xlsx,那么我们要是正常的话就解析不了.这时我们就要用tm-extractors-0.4.jar ...

  7. java office文件加水印_永中Office与统一操作系统UOS完成适配,开辟高效智能办公新领域...

    近日,永中Office办公软件完成了与统一操作系统UOS的适配工作,此次成功适配表明信息技术应用创新操作系统与办公软件兼容性能优良.运行稳定,大幅提升用户在信创计算机上的办公体验,可为政企提供安全可靠 ...

  8. 微信小程序 - 在线预览 Office 文件(doc / docx / xls / xlsx / ppt / pptx / pdf)

    效果图 前言 网上大部分教程功能有问题且文章无逻辑混乱,本文将提供优秀的示例. 本文只适用于预览 服务端接口返回的网络地址文件,"本地上传" 文件并预览原理一样, 例如服务端接口返 ...

  9. POI解析文档内容(txt,doc,docx,xls,xlsx,ppt,pdf)

    Apache POI  是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java程式对Microsoft Office格式档案读和写的功能.POI为" ...

  10. pdf文件加水印怎么加,5个方法快速易学

    PDF文件加水印是一个非常重要且常见的操作,对于不熟悉这一技能的人来说可能会感到困难.这也是为什么在某些浏览器中"pdf文件加水印怎么加"搜索量可高达几百万之多.但是,我们都知道掌 ...

最新文章

  1. keras卷积层用法API
  2. sitemesh排除装饰action的心得
  3. 利用simhash计算文本相似度
  4. 纯CSS打造可折叠树状菜单
  5. 以两台Linux主机在docker中实现mysql主主备份以用nginx实现mysql高可用
  6. 并查集(图论) LA 3644 X-Plosives
  7. cf不能全屏win7的解决方法_win7系统局域网不能访问怎么办 win7局域网不能访问解决方法...
  8. php小猫咪图床源码V1.8
  9. 转换GridView的内容到Excel里面 ---带有格式
  10. PHP实现JS颜文字编码解码过程-aaencode+aadecode
  11. PyQt5系列(一)第一个helloworld
  12. lisp语言cond和if套用_AutoCAD LISP 循环选择语句cond
  13. GBDT 如何用于分类问题
  14. 用简单直白的方式讲解A星寻路算法原理
  15. adb通过usb连接手机
  16. 网络型 PLC可编程控制器综合实训装置
  17. java实现Blowfish算法加密解密
  18. Ubuntu14.04搭建LXR本地服务器阅读Linux内核代码
  19. JQuery 日期选择框,精确到时分秒类型。
  20. 一米OA漏洞学习——getfile.jsp 任意文件读取漏洞

热门文章

  1. Hive调优之 union all 效率低的问题解决
  2. Dynamics CRM 365 - 零基础入门学习后端插件的注册方法
  3. 全局快门和卷帘快门的区别
  4. win10 系统无法远程桌面连接到服务器,Win10系统不能建立远程桌面连接总是连接不上如何解决...
  5. clickhouse 入门介绍和预演
  6. 【LOJ3058】【HNOI2019】白兔之舞
  7. 参数篡改(Parameter Tampering)
  8. 单片机设计 电子琴音乐盒(AT89C51)
  9. Blender3.0资产浏览器
  10. 怎么获取论文所在期刊的电子版封面及目录