java 添加水印(均亲自测试通过)
前言
本地开发环境:jdk1.8
涉及jar:
1)图片:jdk自带的rt.jar
2)pdf:itextpdf-5.5.9.jar、itext-asian.jar
3)docx、doc、wps:aspectjweaver-1.9.1.jar、aspose-words-14.9.0-jdk16.jar
4)xlsx、xls、et(金山的表格格式):
commons-codec-1.4.jar、
poi-3.14-20160307.jar
poi-examples-3.14-20160307.jar
poi-excelant-3.14-20160307.jar
poi-ooxml-3.14-20160307.jar
poi-ooxml-schemas-3.14-20160307.jar
poi-scratchpad-3.14-20160307.jar
xbean.jar
下载地址:https://pan.baidu.com/s/1iEwcOewDG-vGJLtO1NWMcQ
提取码:7df3
正文
1、给图片、pdf添加水印
package com.xxxxx.waterMark;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfGState;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
/**
* itextpdf-5.5.9.jar、itext-asian.jar
* @author sunshine
*
*/
public class WaterMarkUtils {
public static String filePath="C:\\Users\\sunshine\\Desktop\\工作\\waterMark\\";
/**
* @param args
* @throws IOException
* @throws DocumentException
*/
public static void main(String[] args) throws DocumentException, IOException {
// 1、给图片添加文字水印
WaterMarkUtils.setWaterMarkToImageByWords("sunshine", WaterMarkWordUtils.filePath+"1.jpg", WaterMarkWordUtils.filePath+"To1.jpg", 45, Color.blue);
//2、PDF添加动态水印
//要输出的pdf文件
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File("C:\\Users\\sunshine\\Desktop\\工作\\waterMark\\To3.pdf")));
// 将pdf文件先加水印然后输出
WaterMarkUtils.setWaterMarkToPdfByWords(bos, "C:\\Users\\sunshine\\Desktop\\工作\\waterMark\\3.pdf", "sunshine");
}
//============================================1、给图片添加文字水印==================================================
/**
* 图片添加文字水印
* @param logoText
* @param srcImgPath
* @param newImagePath
* @param degree
* @param color
*/
public static void setWaterMarkToImageByWords(String logoText, String srcImgPath,String newImagePath,Integer degree,Color color) {
InputStream is = null;
OutputStream os = null;
try {
// 1、源图片
java.awt.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), java.awt.Image.SCALE_SMOOTH), 0, 0, null);
// 4、设置水印旋转
if (null != degree) {
g.rotate(Math.toRadians(degree), buffImg.getWidth()/2,buffImg.getHeight() /2);
}
// 5、设置水印文字颜色
g.setColor(color);
// 6、设置水印文字Font
g.setFont(new java.awt.Font("宋体", java.awt.Font.BOLD, buffImg.getHeight() /2));
// 7、设置水印文字透明度
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.45f));
// 8、第一参数->设置的内容,后面两个参数->文字在图片上的坐标位置(x,y)
g.drawString(logoText, buffImg.getWidth()/4 , buffImg.getHeight()/4);
// 9、释放资源
g.dispose();
// 10、图片后缀
String formaName = srcImgPath.substring(srcImgPath.lastIndexOf(".")+1, srcImgPath.length());
// 11、生成图片
os = new FileOutputStream(newImagePath);
ImageIO.write(buffImg, formaName, os);
} 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();
}
}
}
//============================================2、PDF添加动态文字水印==================================================
/**
*
* @param bos输出文件的位置
* @param input
* 原PDF位置
* @param waterMarkName
* 页脚添加水印
* @throws DocumentException
* @throws IOException
*/
public static void setWaterMarkToPdfByWords(BufferedOutputStream bos, String input, String waterMarkName)
throws DocumentException, IOException {
PdfReader reader = new PdfReader(input);
PdfStamper stamper = new PdfStamper(reader, bos);
// 获取总页数 +1, 下面从1开始遍历
int total = reader.getNumberOfPages() + 1;
// 使用classpath下面的字体库
BaseFont base = null;
try {
base = BaseFont.createFont("C:\\Users\\sunshine\\Desktop\\工作\\waterMark\\Fonts\\calibri.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_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.4f);
gs.setStrokeOpacity(0.4f);
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();
}
}
2、给docx、doc、wps、xlsx、xls加水印
package com.xxxxx.waterMark;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.imageio.ImageIO;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.ClientAnchor;
import org.apache.poi.ss.usermodel.Drawing;
import org.apache.poi.ss.usermodel.Picture;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import com.aspose.words.Document;
import com.aspose.words.HeaderFooter;
import com.aspose.words.HeaderFooterType;
import com.aspose.words.HorizontalAlignment;
import com.aspose.words.Paragraph;
import com.aspose.words.RelativeHorizontalPosition;
import com.aspose.words.RelativeVerticalPosition;
import com.aspose.words.SaveFormat;
import com.aspose.words.Section;
import com.aspose.words.Shape;
import com.aspose.words.ShapeType;
import com.aspose.words.VerticalAlignment;
import com.aspose.words.WrapType;
public class WaterMarkWordUtils {
//文件路径
public static String filePath="C:\\Users\\sunshine\\Desktop\\工作\\waterMark\\";
public static void main(String[] args) {
try {
//1、给docx加水印
//WaterMarkWordUtils.setWaterMarkToDocxWps("sunshine");
//2、给doc加水印
//WaterMarkWordUtils.setWaterMarkToDoc("sunshine");
//3、给excel加水印
//WaterMarkWordUtils.setWaterMarkToXlsx("sunshine");
WaterMarkWordUtils.setWaterMarkToXlsEt("sunshine");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//============================================1、docx、wps添加文字水印==================================================
/**
* docx添加水印
* @param docx 需要添加水印的word文档
* @param watermark 水印文字内容
* @throws Exception
*/
public static void setWaterMarkToDocxWps(String watermarkText) throws Exception {//获取文件输出流
//FileOutputStream os = new FileOutputStream(WaterMarkWordUtils.filePath+"To4.docx");
FileOutputStream os = new FileOutputStream(WaterMarkWordUtils.filePath+"To9.wps");
//获取Doc文档对象模型
//Document doc = new Document(WaterMarkWordUtils.filePath+"4.docx");
Document doc = new Document(WaterMarkWordUtils.filePath+"9.wps");
Shape watermark = new Shape(doc, ShapeType.TEXT_PLAIN_TEXT);
//水印内容
watermark.getTextPath().setText(watermarkText);
//水印字体
watermark.getTextPath().setFontFamily("宋体");
//水印宽度
watermark.setWidth(500);
//水印高度
watermark.setHeight(100);
//旋转水印
watermark.setRotation(-40);
//水印颜色
watermark.getFill().setColor(Color.lightGray);
watermark.setStrokeColor(Color.lightGray);
watermark.setRelativeHorizontalPosition(RelativeHorizontalPosition.PAGE);
watermark.setRelativeVerticalPosition(RelativeVerticalPosition.PAGE);
watermark.setWrapType(WrapType.NONE);
watermark.setVerticalAlignment(VerticalAlignment.CENTER);
watermark.setHorizontalAlignment(HorizontalAlignment.CENTER);
Paragraph watermarkPara = new Paragraph(doc);
watermarkPara.appendChild(watermark);
for (Section sect : doc.getSections())
{
insertWatermarkIntoHeader(watermarkPara, sect, HeaderFooterType.HEADER_PRIMARY);
insertWatermarkIntoHeader(watermarkPara, sect, HeaderFooterType.HEADER_FIRST);
insertWatermarkIntoHeader(watermarkPara, sect, HeaderFooterType.HEADER_EVEN);
}
System.out.println("Watermark Set");
doc.save(os, SaveFormat.DOCX);
//关闭输出流
if(os!=null){
os.close();
}
}
//============================================2、doc添加水印==================================================
/**
* 给doc加水印
*/
public static void setWaterMarkToDoc(String watermarkText) throws Exception{
//获取文件输出流
FileOutputStream os = new FileOutputStream(WaterMarkWordUtils.filePath+"To5.doc");
//FileOutputStream os = new FileOutputStream(WaterMarkWordUtils.filePath+"To10.wpt");
//获取Doc文档对象模型
Document doc = new Document(WaterMarkWordUtils.filePath+"5.doc");
//Document doc = new Document(WaterMarkWordUtils.filePath+"10.wpt");
Shape watermark = new Shape(doc, ShapeType.TEXT_PLAIN_TEXT);
//水印内容
watermark.getTextPath().setText(watermarkText);
//水印字体
watermark.getTextPath().setFontFamily("宋体");
//水印宽度
watermark.setWidth(500);
//水印高度
watermark.setHeight(100);
//旋转水印
watermark.setRotation(-40);
//水印颜色
watermark.getFill().setColor(Color.lightGray);
watermark.setStrokeColor(Color.lightGray);
watermark.setRelativeHorizontalPosition(RelativeHorizontalPosition.PAGE);
watermark.setRelativeVerticalPosition(RelativeVerticalPosition.PAGE);
watermark.setWrapType(WrapType.NONE);
watermark.setVerticalAlignment(VerticalAlignment.CENTER);
watermark.setHorizontalAlignment(HorizontalAlignment.CENTER);
Paragraph watermarkPara = new Paragraph(doc);
watermarkPara.appendChild(watermark);
for (Section sect : doc.getSections())
{
insertWatermarkIntoHeader(watermarkPara, sect, HeaderFooterType.HEADER_PRIMARY);
insertWatermarkIntoHeader(watermarkPara, sect, HeaderFooterType.HEADER_FIRST);
insertWatermarkIntoHeader(watermarkPara, sect, HeaderFooterType.HEADER_EVEN);
}
System.out.println("Watermark Set");
doc.save(os, SaveFormat.DOC);
//关闭输出流
if(os!=null){
os.close();
}
}
/**
* 在页眉中插入水印
* @param watermarkPara
* @param sect
* @param headerType
* @throws Exception
*/
private static void insertWatermarkIntoHeader(Paragraph watermarkPara, Section sect, int headerType) throws Exception{
HeaderFooter header = sect.getHeadersFooters().getByHeaderFooterType(headerType);
if (header == null)
{
header = new HeaderFooter(sect.getDocument(), headerType);
sect.getHeadersFooters().add(header);
}
header.appendChild(watermarkPara.deepClone(true));
}
//============================================3、excel添加水印==================================================
/**
* xlsx添加水印
* @param watermarkText
* @throws Exception
*/
public static void setWaterMarkToXlsx(String watermarkText) throws Exception{
XSSFWorkbook wb = new XSSFWorkbook(new FileInputStream(WaterMarkWordUtils.filePath+"7.xlsx"));
XSSFSheet sheet = wb.getSheetAt(0);//测试暂取第一个工作簿
//添加水印
WaterMarkWordUtils.waterMarkExcel(wb,sheet,watermarkText);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
wb.write(bos);
wb.close();
byte[] content = bos.toByteArray();
OutputStream out = null;
out = new FileOutputStream(WaterMarkWordUtils.filePath+"To7.xlsx");
out.write(content);
bos.close();
out.close();
}
/**
* xls、et(金山)添加水印
* @param watermarkText
* @throws Exception
*/
public static void setWaterMarkToXlsEt(String watermarkText) throws Exception{
//HSSFWorkbook wb = new HSSFWorkbook(new FileInputStream(WaterMarkWordUtils.filePath+"8.xls"));
HSSFWorkbook wb = new HSSFWorkbook(new FileInputStream(WaterMarkWordUtils.filePath+"11.et"));
HSSFSheet sheet = wb.getSheetAt(0);//测试暂取第一个工作簿
//添加水印
WaterMarkWordUtils.waterMarkExcel(wb,sheet,watermarkText);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
wb.write(bos);
wb.close();
byte[] content = bos.toByteArray();
OutputStream out = null;
//out = new FileOutputStream(WaterMarkWordUtils.filePath+"To8.xls");
out = new FileOutputStream(WaterMarkWordUtils.filePath+"To11.et");
out.write(content);
bos.close();
out.close();
}
/**
*
* @param wb
* @param sheet 需要打水印的excel工作簿
* @param imPath 水印文字
*/
private static void waterMarkExcel(Workbook wb,Sheet sheet,String watermarkText) throws Exception {
ByteArrayOutputStream ByteArrayOut = new ByteArrayOutputStream();
//加载图片
/*InputStream imageIn = new FileInputStream(imPath);
BufferedImage bufferImg = ImageIO.read(imageIn);*/
BufferedImage bufferImg =ImageUtil.getImage(watermarkText);
ImageIO.write(bufferImg, "png", ByteArrayOut);
//开始打水印
Drawing drawing = sheet.createDrawingPatriarch();//
ClientAnchor anchor = drawing.createAnchor(1, 1, 2, 2, 1, 1, 2, 2);
Picture pic = drawing.createPicture(anchor,wb.addPicture(ByteArrayOut.toByteArray(), Workbook.PICTURE_TYPE_PNG));
pic.resize();
}
}
上面“excel添加水印”的方法中,是生成了一个带文字的水印图片,然后把图片加到excel中,“生成带文字的水印图片”的方法整理了工具类,如下:
package com.xxxxx.waterMark;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.OutputStream;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
public class ImageUtil {
public static void main(String[] args) {
try {
ImageUtil.getImage("sunshine");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 创建新的图片
*/
public static BufferedImage getImage(String waterMarkContent) throws Exception {
int width = 150;
int height =150;
BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = (Graphics2D) bi.getGraphics();
g2.setBackground(Color.WHITE);
g2.clearRect(0, 0, width, height);
return addWatermark(bi, waterMarkContent);
}
/**
* @description 生成水印图片
* @param sourceImgPath 源图片路径
* @param waterMarkContent 水印内容
*/
public static BufferedImage addWatermark(BufferedImage sourceImgPath, String waterMarkContent) {
// 水印字体,大小
Font font = new Font("宋体", Font.BOLD, 28);
// 水印颜色
Color markContentColor = Color.blue;
// 设置水印文字的旋转角度
Integer degree = -45;
// 设置水印透明度
float alpha = 0.5f;
OutputStream outImgStream = null;
try {
// 文件转化为图片
Image srcImg = sourceImgPath;
// 获取图片的宽
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);
// 设置水印颜色
g.setColor(markContentColor);
// 设置字体
g.setFont(font);
// 设置水印文字透明度
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
if (null != degree) {
// 设置水印旋转
g.rotate(Math.toRadians(degree));
}
// 画出水印,并设置水印位置
g.drawString(waterMarkContent, -88, 120);
// 释放资源
g.dispose();
return transferAlpha(bufImg);
} catch (Exception e) {
e.printStackTrace();
e.getMessage();
} finally {
try {
if (outImgStream != null) {
outImgStream.flush();
outImgStream.close();
}
} catch (Exception e) {
e.printStackTrace();
e.getMessage();
}
}
return null;
}
/**
* @description 转化成透明背景的图片
* @param bufImg 源图片
*/
public static BufferedImage transferAlpha(BufferedImage bufImg) {
try {
Image image = bufImg;
ImageIcon imageIcon = new ImageIcon(image);
BufferedImage bufferedImage = new BufferedImage(imageIcon.getIconWidth(), imageIcon.getIconHeight(),
BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D g2D = (Graphics2D) bufferedImage.getGraphics();
g2D.drawImage(imageIcon.getImage(), 0, 0, imageIcon.getImageObserver());
int alpha = 0;
for (int j1 = bufferedImage.getMinY(); j1 < bufferedImage.getHeight(); j1++) {
for (int j2 = bufferedImage.getMinX(); j2 < bufferedImage.getWidth(); j2++) {
int rgb = bufferedImage.getRGB(j2, j1);
int R = (rgb & 0xff0000) >> 16;
int G = (rgb & 0xff00) >> 8;
int B = (rgb & 0xff);
if (((255 - R) < 30) && ((255 - G) < 30) && ((255 - B) < 30)) {
rgb = ((alpha + 1) << 24) | (rgb & 0x00ffffff);
}
bufferedImage.setRGB(j2, j1, rgb);
}
}
g2D.drawImage(bufferedImage, 0, 0, imageIcon.getImageObserver());
// 直接输出文件用来测试结果
//ImageIO.write(bufImg, "png", new File("C:\\Users\\sunshine\\Desktop\\工作\\waterMark\\8-1.png"));
return bufferedImage;
} catch (Exception e) {
e.printStackTrace();
} finally {
}
return null;
}
}
以上方法均亲自测试通过,仅作为demo使用,实际开发肯定需要进行进一步抽取优化
版权声明:本文为u011293064原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。