|
@@ -0,0 +1,577 @@
|
|
|
+package com.caimei.modules.archive.utils;
|
|
|
+
|
|
|
+import com.itextpdf.text.*;
|
|
|
+import com.itextpdf.text.Rectangle;
|
|
|
+import com.itextpdf.text.pdf.*;
|
|
|
+import com.thinkgem.jeesite.common.config.Global;
|
|
|
+import groovy.util.logging.Slf4j;
|
|
|
+import org.apache.poi.POIXMLDocument;
|
|
|
+import org.apache.poi.hwpf.HWPFDocument;
|
|
|
+import org.apache.poi.openxml4j.opc.OPCPackage;
|
|
|
+import org.apache.poi.sl.usermodel.PictureData;
|
|
|
+import org.apache.poi.sl.usermodel.PictureData.PictureType;
|
|
|
+import org.apache.poi.ss.usermodel.*;
|
|
|
+import org.apache.poi.xslf.usermodel.*;
|
|
|
+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.model.XWPFHeaderFooterPolicy;
|
|
|
+import org.apache.poi.xwpf.usermodel.XWPFDocument;
|
|
|
+import org.apache.poi.xwpf.usermodel.XWPFHeader;
|
|
|
+import org.apache.poi.xwpf.usermodel.XWPFParagraph;
|
|
|
+import org.slf4j.Logger;
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
+import schemasMicrosoftComVml.CTShape;
|
|
|
+
|
|
|
+import javax.imageio.ImageIO;
|
|
|
+import javax.swing.*;
|
|
|
+import java.awt.Color;
|
|
|
+import java.awt.Font;
|
|
|
+import java.awt.*;
|
|
|
+import java.awt.Image;
|
|
|
+import java.awt.font.FontRenderContext;
|
|
|
+import java.awt.geom.Rectangle2D;
|
|
|
+import java.awt.image.BufferedImage;
|
|
|
+import java.io.*;
|
|
|
+import java.lang.reflect.Field;
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ * Description
|
|
|
+ *
|
|
|
+ * @author : Charles
|
|
|
+ * @date : 2021/9/18
|
|
|
+ */
|
|
|
+public class WaterMarkUtils {
|
|
|
+
|
|
|
+ private final static String outPath = Global.getConfig("archive.tempPath");
|
|
|
+ /**
|
|
|
+ * 日志对象
|
|
|
+ */
|
|
|
+ private static Logger log = LoggerFactory.getLogger(WaterMarkUtils.class);
|
|
|
+
|
|
|
+ // 水印透明度
|
|
|
+ private static float alpha = 0.5f;
|
|
|
+ // 水印之间的间隔
|
|
|
+ private static final int XMOVE = 200;
|
|
|
+ // 水印之间的间隔
|
|
|
+ private static final int YMOVE = 200;
|
|
|
+
|
|
|
+ public static void main(String[] args) {
|
|
|
+ /*addPictureWaterMark("D:\\WorkSpace\\file\\img.jpg", "D:\\WorkSpace\\file\\temp\\img1.jpg", "我是水印");
|
|
|
+ setPictureWatermark("D:\\WorkSpace\\file\\img.jpg", "D:\\WorkSpace\\file\\temp\\img2.jpg", Color.GRAY, "我是水印");
|
|
|
+// setWordWaterMark("D:\\WorkSpace\\file\\test.doc", "D:\\WorkSpace\\file\\temp\\test.doc", "我是水印", "doc");
|
|
|
+ setWordWaterMark("D:\\WorkSpace\\file\\test.docx", "D:\\WorkSpace\\file\\temp\\test.docx", "我是水印", "docx");
|
|
|
+ setPdfWatermark("D:\\WorkSpace\\file\\test.pdf", "D:\\WorkSpace\\file\\temp\\test.pdf", "我是水印");
|
|
|
+// setExcelWaterMark("D:\\WorkSpace\\file\\test.xls", "D:\\WorkSpace\\file\\temp\\test.xls", "我是水印");
|
|
|
+// setPPTWaterMark("D:\\WorkSpace\\file\\test.ppt", "D:\\WorkSpace\\file\\temp\\test.ppt", "我是水印");
|
|
|
+ setPPTWaterMark("D:\\WorkSpace\\file\\test.pptx", "D:\\WorkSpace\\file\\temp\\test.pptx", "我是水印");
|
|
|
+ */}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @param srcImgPath 源图片路径
|
|
|
+ * @param tarImgPath 保存的图片路径
|
|
|
+ * @param waterMarkContent 水印内容
|
|
|
+ */
|
|
|
+ public static void addPictureWaterMark(String srcImgPath, String tarImgPath,
|
|
|
+ String waterMarkContent) {
|
|
|
+ FileOutputStream outImgStream = null;
|
|
|
+ try {
|
|
|
+ // 读取原图片信息
|
|
|
+ File srcImgFile = new File(srcImgPath);// 得到文件
|
|
|
+ Image srcImg = ImageIO.read(srcImgFile);// 文件转化为图片
|
|
|
+ int srcImgWidth = srcImg.getWidth(null);// 获取图片的宽
|
|
|
+ int srcImgHeight = srcImg.getHeight(null);// 获取图片的高
|
|
|
+ // 加水印
|
|
|
+ BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight,
|
|
|
+ BufferedImage.TYPE_INT_RGB);
|
|
|
+ Graphics2D g = bufImg.createGraphics();
|
|
|
+ // 设置对线段的锯齿状边缘处理
|
|
|
+ g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
|
|
|
+ RenderingHints.VALUE_INTERPOLATION_BILINEAR);
|
|
|
+ g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);
|
|
|
+ // 设置水印旋转
|
|
|
+ g.rotate(Math.toRadians(-40),
|
|
|
+ (double) bufImg.getWidth() / 2,
|
|
|
+ (double) bufImg.getHeight() / 2);
|
|
|
+ g.setColor(new Color(107, 109, 106)); // 根据图片的背景设置水印颜色
|
|
|
+ Font font = new Font("宋体", Font.PLAIN, 20);
|
|
|
+ g.setFont(font); // 设置字体
|
|
|
+ // 设置水印文字透明度
|
|
|
+// g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP,alpha));
|
|
|
+
|
|
|
+ //根据不同的像素判断多个水印还是单个水印300*300
|
|
|
+ if (srcImgWidth > 300 && srcImgHeight > 300) {
|
|
|
+ //多个水印
|
|
|
+ // 设置水印的坐标
|
|
|
+ int x = -srcImgWidth / 2;
|
|
|
+ int y = -srcImgHeight / 2;
|
|
|
+ int markWidth = font.getSize() * getTextLength(waterMarkContent);// 字体长度
|
|
|
+ int markHeight = font.getSize();// 字体高度
|
|
|
+ // 循环添加水印
|
|
|
+ while (x < srcImgWidth * 1.5) {
|
|
|
+ y = -srcImgHeight / 2;
|
|
|
+ while (y < srcImgHeight * 1.5) {
|
|
|
+ g.drawString(waterMarkContent, x, y);
|
|
|
+ y += markHeight + YMOVE;
|
|
|
+ }
|
|
|
+ x += markWidth + XMOVE;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ //单个水印
|
|
|
+ int x = (srcImgWidth - getWatermarkLength(waterMarkContent, g)) / 2;
|
|
|
+ int y = srcImgHeight / 2;
|
|
|
+ g.drawString(waterMarkContent, x, y);
|
|
|
+ }
|
|
|
+ g.dispose();
|
|
|
+ // 输出图片
|
|
|
+ outImgStream = new FileOutputStream(tarImgPath);
|
|
|
+ String formatName = srcImgPath.substring(srcImgPath.lastIndexOf(".") + 1, srcImgPath.length());
|
|
|
+ ImageIO.write(bufImg, formatName, outImgStream);
|
|
|
+ outImgStream.flush();
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("addPictureWatermark fail", e);
|
|
|
+ // throw new MyException(ResultCode.FAILURE, "addPictureWatermark fail");
|
|
|
+ } finally {
|
|
|
+ if (outImgStream != null) {
|
|
|
+ try {
|
|
|
+ outImgStream.close();
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 图片添加水印
|
|
|
+ *
|
|
|
+ * @param srcImgPath 需要添加水印的图片的路径
|
|
|
+ * @param outImgPath 添加水印后图片输出路径
|
|
|
+ * @param markContentColor 水印文字的颜色
|
|
|
+ * @param waterMarkContent 水印的文字
|
|
|
+ */
|
|
|
+ public static void setPictureWatermark(String srcImgPath, String outImgPath, Color markContentColor, String waterMarkContent) {
|
|
|
+ FileOutputStream outImgStream = null;
|
|
|
+ try {
|
|
|
+ // 读取原图片信息
|
|
|
+ File srcImgFile = new File(srcImgPath);
|
|
|
+ Image srcImg = ImageIO.read(srcImgFile);
|
|
|
+ int srcImgWidth = srcImg.getWidth(null);
|
|
|
+ int srcImgHeight = srcImg.getHeight(null);
|
|
|
+ // 加水印
|
|
|
+ BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);
|
|
|
+ Graphics2D g = bufImg.createGraphics();
|
|
|
+ g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);
|
|
|
+ Font font = new Font("宋体", Font.BOLD, srcImgHeight / 6);
|
|
|
+ //根据图片的背景设置水印颜色
|
|
|
+ g.setColor(markContentColor);
|
|
|
+ //设置旋转角度
|
|
|
+ g.rotate(Math.toRadians(-45), (double) bufImg.getWidth() / 2, (double) bufImg.getHeight() / 2);
|
|
|
+ //设置水印透明度
|
|
|
+ g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.2F));
|
|
|
+
|
|
|
+ g.setFont(font);
|
|
|
+ int x = (srcImgWidth - getWatermarkLength(waterMarkContent, g)) / 2;
|
|
|
+ int y = srcImgHeight / 2;
|
|
|
+ g.drawString(waterMarkContent, x, y);
|
|
|
+ g.dispose();
|
|
|
+ // 输出图片
|
|
|
+ outImgStream = new FileOutputStream(outImgPath);
|
|
|
+ ImageIO.write(bufImg, "jpg", outImgStream);
|
|
|
+ outImgStream.flush();
|
|
|
+ outImgStream.close();
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("setPictureWatermark fail", e);
|
|
|
+ // throw new MyException(ResultCode.FAILURE, "setPictureWatermark fail");
|
|
|
+ } finally {
|
|
|
+ if (outImgStream != null) {
|
|
|
+ try {
|
|
|
+ outImgStream.close();
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * word文字水印
|
|
|
+ *
|
|
|
+ * @param markStr
|
|
|
+ */
|
|
|
+ public static void setWordWaterMark(File inputFile, String markStr,String filePath, String fileType) {
|
|
|
+ if ("docx".equals(fileType)) {
|
|
|
+ //2003doc 用HWPFDocument ; 2007doc 用 XWPFDocument
|
|
|
+ XWPFDocument doc = null;
|
|
|
+ try {
|
|
|
+// OPCPackage pack = POIXMLDocument.openPackage(inputPath);
|
|
|
+// doc = new XWPFDocument(pack);
|
|
|
+ doc = new XWPFDocument(new FileInputStream(inputFile));
|
|
|
+// doc = new XWPFDocument(new FileInputStream(inputFile));
|
|
|
+ } catch (FileNotFoundException e) {
|
|
|
+ log.error("setWordWaterMark fail: 源文件不存在", e);
|
|
|
+ // throw new MyException(ResultCode.FAILURE, "setWordWaterMark fail: 源文件不存在");
|
|
|
+ } catch (IOException e) {
|
|
|
+ log.error("setWordWaterMark fail: 读取源文件IO异常", e);
|
|
|
+ // throw new MyException(ResultCode.FAILURE, "setWordWaterMark fail: 读取源文件IO异常");
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("setWordWaterMark fail: 不支持的文档格式", e);
|
|
|
+ // throw new MyException(ResultCode.FAILURE, "setWordWaterMark fail: 不支持的文档格式");
|
|
|
+ }
|
|
|
+ XWPFParagraph paragraph = doc.createParagraph();
|
|
|
+ XWPFHeaderFooterPolicy headerFooterPolicy = doc.getHeaderFooterPolicy();
|
|
|
+ if (headerFooterPolicy == null) {
|
|
|
+ headerFooterPolicy = doc.createHeaderFooterPolicy();
|
|
|
+ }
|
|
|
+ // create default Watermark - fill color black and not rotated
|
|
|
+ headerFooterPolicy.createWatermark(markStr);
|
|
|
+ // get the default header
|
|
|
+ // Note: createWatermark also sets FIRST and EVEN headers
|
|
|
+ // but this code does not updating those other headers
|
|
|
+ XWPFHeader header = headerFooterPolicy.getHeader(XWPFHeaderFooterPolicy.DEFAULT);
|
|
|
+ paragraph = header.getParagraphArray(0);
|
|
|
+// // get com.microsoft.schemas.vml.CTShape where fill color and rotation is set
|
|
|
+// paragraph.getCTP().newCursor();
|
|
|
+// System.out.println(paragraph.getCTP().getRArray(0));
|
|
|
+// System.out.println(paragraph.getCTP().getRArray(0).getPictArray(0));
|
|
|
+ org.apache.xmlbeans.XmlObject[] xmlobjects = paragraph.getCTP().getRArray(0).getPictArray(0).selectChildren(
|
|
|
+ new javax.xml.namespace.QName("urn:schemas-microsoft-com:vml", "shape"));
|
|
|
+ if (xmlobjects.length > 0) {
|
|
|
+ com.microsoft.schemas.vml.CTShape ctshape = (com.microsoft.schemas.vml.CTShape) xmlobjects[0];
|
|
|
+ ctshape.setFillcolor("#D3D3D3");
|
|
|
+ ctshape.setStyle(ctshape.getStyle() + ";rotation:315" + ";height:60pt;width:360pt");
|
|
|
+ }
|
|
|
+ File file = new File(outPath + filePath);
|
|
|
+ if (!file.exists()) {
|
|
|
+ try {
|
|
|
+ file.createNewFile();
|
|
|
+ } catch (IOException e) {
|
|
|
+ log.error("setWordWaterMark fail: 创建输出文件IO异常", e);
|
|
|
+ // throw new MyException(ResultCode.FAILURE, "setWordWaterMark fail: 创建输出文件失败");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ doc.write(new FileOutputStream(outPath + filePath));
|
|
|
+ } catch (FileNotFoundException e) {
|
|
|
+ log.error("setWordWaterMark fail: 输出文件不存在", e);
|
|
|
+ // throw new MyException(ResultCode.FAILURE, "setWordWaterMark fail: 创建输出文件失败");
|
|
|
+ } catch (IOException e) {
|
|
|
+ log.error("setWordWaterMark fail: ", e);
|
|
|
+ // throw new MyException(ResultCode.FAILURE, "setWordWaterMark fail");
|
|
|
+ } finally {
|
|
|
+ if (doc != null) {
|
|
|
+ try {
|
|
|
+ doc.close();
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * pdf设置文字水印
|
|
|
+ *
|
|
|
+ * @param inputPath
|
|
|
+ * @param outPath
|
|
|
+ * @param markStr
|
|
|
+ */
|
|
|
+ public static void setPdfWatermark(String inputPath, String outPath, String markStr) {
|
|
|
+ File file = new File(outPath);
|
|
|
+ if (!file.exists()) {
|
|
|
+ try {
|
|
|
+ file.createNewFile();
|
|
|
+ } catch (IOException e) {
|
|
|
+ log.error("setPdfWatermark fail: 创建输出文件IO异常", e);
|
|
|
+ // throw new MyException(ResultCode.FAILURE, "setPdfWatermark fail: 创建输出文件IO异常");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ BufferedOutputStream bufferOut = null;
|
|
|
+ try {
|
|
|
+ bufferOut = new BufferedOutputStream(new FileOutputStream(file));
|
|
|
+ } catch (FileNotFoundException e) {
|
|
|
+ log.error("setPdfWatermark fail: 源文件不存在", e);
|
|
|
+ // throw new MyException(ResultCode.FAILURE, "setPdfWatermark fail: 源文件不存在");
|
|
|
+ }
|
|
|
+ PdfStamper stamper = null;
|
|
|
+ int total = 0;
|
|
|
+ PdfContentByte content;
|
|
|
+ Rectangle pageSizeWithRotation = null;
|
|
|
+ BaseFont base = null;
|
|
|
+ PdfReader reader = null;
|
|
|
+ try {
|
|
|
+ reader = new PdfReader(inputPath);
|
|
|
+ //解决PdfReader not opened with owner password
|
|
|
+ Field f = PdfReader.class.getDeclaredField("ownerPasswordUsed");
|
|
|
+ f.setAccessible(true);
|
|
|
+ f.set(reader, Boolean.TRUE);
|
|
|
+ stamper = new PdfStamper(reader, bufferOut);
|
|
|
+ total = reader.getNumberOfPages() + 1;
|
|
|
+ base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.EMBEDDED);
|
|
|
+ } catch (IOException e) {
|
|
|
+ log.error("setPdfWatermark fail:", e);
|
|
|
+ // throw new MyException(ResultCode.FAILURE, "setPdfWatermark fail");
|
|
|
+ } catch (DocumentException e) {
|
|
|
+ log.error("setPdfWatermark fail:", e);
|
|
|
+ // throw new MyException(ResultCode.FAILURE, "setPdfWatermark fail");
|
|
|
+ } catch (IllegalAccessException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ } catch (NoSuchFieldException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ // 获取水印文字的高度和宽度
|
|
|
+ int textH = 0, textW = 0;
|
|
|
+ JLabel label = new JLabel();
|
|
|
+ label.setText(markStr);
|
|
|
+ FontMetrics metrics = label.getFontMetrics(label.getFont());
|
|
|
+ textH = metrics.getHeight();
|
|
|
+ textW = metrics.stringWidth(label.getText());
|
|
|
+ PdfGState gs = new PdfGState();
|
|
|
+ for (int i = 1; i < total; i++) {
|
|
|
+ //在内容上方加水印
|
|
|
+ content = stamper.getOverContent(i);
|
|
|
+ gs.setFillOpacity(0.5f);
|
|
|
+ content.saveState();
|
|
|
+ content.setGState(gs);
|
|
|
+ content.beginText();
|
|
|
+// content.setRGBColorFill(0, 0, 0);
|
|
|
+ content.setFontAndSize(base, 20);
|
|
|
+ // 获取每一页的高度、宽度
|
|
|
+ pageSizeWithRotation = reader.getPageSizeWithRotation(i);
|
|
|
+ float pageHeight = pageSizeWithRotation.getHeight();
|
|
|
+ float pageWidth = pageSizeWithRotation.getWidth();
|
|
|
+
|
|
|
+ // 根据纸张大小多次添加, 水印文字成30度角倾斜
|
|
|
+ for (int height = -5 + textH; height < pageHeight; height = height + YMOVE) {
|
|
|
+ for (int width = -5 + textW; width < pageWidth + textW; width = width + XMOVE) {
|
|
|
+ content.showTextAligned(Element.ALIGN_LEFT, markStr, width - textW, height - textH, 30);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ content.endText();
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ stamper.close();
|
|
|
+ bufferOut.flush();
|
|
|
+ bufferOut.close();
|
|
|
+ reader.close();
|
|
|
+ } catch (IOException e) {
|
|
|
+ log.error("setPdfWatermark fail:", e);
|
|
|
+ // throw new MyException(ResultCode.FAILURE, "setPdfWatermark fail");
|
|
|
+ } catch (DocumentException e) {
|
|
|
+ log.error("setPdfWatermark fail:", e);
|
|
|
+ // throw new MyException(ResultCode.FAILURE, "setPdfWatermark fail");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * excel设置水印
|
|
|
+ *
|
|
|
+ * @param inputPath
|
|
|
+ * @param outPath
|
|
|
+ * @param markStr
|
|
|
+ */
|
|
|
+ public static void setExcelWaterMark(String inputPath, String outPath, String markStr) {
|
|
|
+ //读取excel文件
|
|
|
+ XSSFWorkbook workbook = null;
|
|
|
+ try {
|
|
|
+ workbook = new XSSFWorkbook(new FileInputStream(inputPath));
|
|
|
+ } catch (FileNotFoundException e) {
|
|
|
+ log.error("setExcelWaterMark fail: 源文件不存在", e);
|
|
|
+ // throw new MyException(ResultCode.FAILURE, "setExcelWaterMark fail: 源文件不存在");
|
|
|
+ } catch (IOException e) {
|
|
|
+ log.error("setExcelWaterMark fail: 读取源文件IO异常", e);
|
|
|
+ //throw new MyException(ResultCode.FAILURE, "setExcelWaterMark fail: 读取源文件IO异常");
|
|
|
+ }
|
|
|
+ OutputStream fos = null;
|
|
|
+ ByteArrayOutputStream os = null;
|
|
|
+ try {
|
|
|
+ //获取水印
|
|
|
+ os = getImage(markStr);
|
|
|
+ int pictureIdx = workbook.addPicture(os.toByteArray(), Workbook.PICTURE_TYPE_PNG);
|
|
|
+ for (int i = 0; i < workbook.getNumberOfSheets(); i++) {//获取每个Sheet表
|
|
|
+ XSSFSheet sheet1 = workbook.getSheetAt(i);
|
|
|
+ String rID = sheet1.addRelation(null, XSSFRelation.IMAGES, workbook.getAllPictures().get(pictureIdx)).getRelationship().getId();
|
|
|
+ //set background picture to sheet
|
|
|
+ sheet1.getCTWorksheet().addNewPicture().setId(rID);
|
|
|
+ }
|
|
|
+ // Excel文件生成后存储的位置。
|
|
|
+ File file = new File(outPath);
|
|
|
+ fos = new FileOutputStream(file);
|
|
|
+ workbook.write(fos);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("setExcelWaterMark fail: 创建输出文件IO异常", e);
|
|
|
+ // throw new MyException(ResultCode.FAILURE, "setExcelWaterMark fail: 创建输出文件IO异常");
|
|
|
+ } finally {
|
|
|
+ if (os != null) {
|
|
|
+ try {
|
|
|
+ os.close();
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (fos != null) {
|
|
|
+ try {
|
|
|
+ fos.close();
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (workbook != null) {
|
|
|
+ try {
|
|
|
+ workbook.close();
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 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 MyException(ResultCode.FAILURE, "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 MyException(ResultCode.FAILURE, "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 waterMarkContent 水印的文字
|
|
|
+ * @param g
|
|
|
+ * @return 水印文字总长度
|
|
|
+ */
|
|
|
+ public static int getWatermarkLength(String waterMarkContent, Graphics2D g) {
|
|
|
+ return g.getFontMetrics(g.getFont()).charsWidth(waterMarkContent.toCharArray(), 0, waterMarkContent.length());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取文本长度。汉字为1:1,英文和数字为2:1
|
|
|
+ */
|
|
|
+ private static int getTextLength(String text) {
|
|
|
+ int length = text.length();
|
|
|
+ for (int i = 0; i < text.length(); i++) {
|
|
|
+ String s = String.valueOf(text.charAt(i));
|
|
|
+ if (s.getBytes().length > 1) {
|
|
|
+ length++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ length = length % 2 == 0 ? length / 2 : length / 2 + 1;
|
|
|
+ return length;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取水印文字图片流
|
|
|
+ *
|
|
|
+ * @param text
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private static ByteArrayOutputStream getImage(String text) {
|
|
|
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
|
|
|
+ try {
|
|
|
+ // 导出到字节流B
|
|
|
+ BufferedImage 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;
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void addWaterMark(File inputFile, String markStr, String filePath, String fileType) {
|
|
|
+ if (fileType.contains("doc")) {
|
|
|
+ setWordWaterMark(inputFile, markStr, filePath, fileType);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|