package util;
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.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.imageio.ImageIO;
import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.ComThread;
import com.jacob.com.Dispatch;
import com.jacob.com.Variant;
import com.lowagie.text.Element;
import com.lowagie.text.pdf.BaseFont;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfGState;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfStamper;
/**
*
* @author HWL_SZ
* @version [版本号]
* @see [相关类/方法]
* @since [产品/模块版本]
*/
publicclass WaterMark
{
/**
* @param args
*/
publicstaticvoid main(String[] args) throws Exception
{
String waterMark = "2013公司内部文件,请注意保密!";
String footerMark = "打印时间:"+ new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date())
+ " 打印人:" + "HWL_SZ";
WaterMark.writePdfMark("E:/20131028.pdf", "E:/20131028_water.pdf", waterMark, footerMark);
WaterMark.writeImgMark("E://psb.jpg", "E://psb_water.jpg", waterMark, footerMark);
WaterMark.writeDocMark("E://20131024.doc", "E://20131024_water.doc", waterMark , footerMark);
}
/**
* pdf加水印号
* @param sourceImg 源文件路径
* @param targetImg 加水印号文件输出路径
* @param waterMark 背景水印号
* @param footerMark 页脚文字
* @return加水印号文件输出路径
* @throws Exception
*/
publicstatic String writePdfMark(String sourcePdf, String targetPdf,String waterMark, String footerMark)
throws Exception
{
// 未加水印的源文件
PdfReader reader = new PdfReader(sourcePdf);
// 加完水印的输出文件
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(targetPdf));
// pdf总页数
int total = reader.getNumberOfPages() + 1;
// 设置字体
BaseFont base = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H",
BaseFont.EMBEDDED);
PdfGState gs = new PdfGState();
// 对每页加入水印
for (int i = 1; i < total; i++) {
PdfContentByte content = stamper.getOverContent(i);
gs.setFillOpacity(0.2f);
content.beginText();
// 字体颜色
content.setColorFill(Color.LIGHT_GRAY);
// 字体编码和大小
content.setFontAndSize(base, 50);
/**
* 写入背景水印
* 参数说明
* 1:对齐方式
* 2:水印内容
* 3:左边距
* 4:底边距
* 5:倾斜度
*/
if (null != waterMark && !"".equals(waterMark.trim()))
{
content.showTextAligned(Element.ALIGN_CENTER, waterMark, 300,
350, 60);
}
/**
* 页脚
*/
content.setColorFill(Color.BLACK);
content.setFontAndSize(base, 8);
if (null != footerMark && !"".equals(footerMark.trim()))
{
content.showTextAligned(Element.ALIGN_CENTER, footerMark, 300, 10, 0);
}
content.endText();
}
stamper.close();
return footerMark;
}
/**
* 图片加水印号
* @param sourceImg 源文件路径
* @param targetImg 加水印号文件输出路径
* @param waterMark 背景水印号
* @param footerMark 页脚文字
* @return加水印号文件输出路径
* @throws Exception
*/
publicstatic String writeImgMark(String sourceImg, String targetImg,String waterMark, String footerMark)
{
OutputStream os = null;
String postfix = getPostfix(sourceImg);
try
{
Image srcImg = ImageIO.read(new File(sourceImg));
int width = srcImg.getWidth(null);
int height = srcImg.getHeight(null);
//计算水印文字旋转角度
double degree = Math.atan((double) height/width );
BufferedImage buffImg = null;
if("png".equalsIgnoreCase(postfix.toLowerCase()))
{
buffImg = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
}
else
{
buffImg = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
}
// 得到画笔对象
Graphics2D g = buffImg.createGraphics();
// 设置对线段的锯齿状边缘处理
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.drawImage(srcImg.getScaledInstance(width, height, Image.SCALE_SMOOTH), 0,0, null);
// 设置透明度
float alpha = 0.3f;
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
Font font = new Font("宋体", Font.CENTER_BASELINE, 30);
g.setFont(font);
g.setColor(Color.black);
FontMetrics fm = g.getFontMetrics(font);
int textWidth;
// 水印号
if (null != waterMark && !"".equals(waterMark.trim()))
{
textWidth = fm.stringWidth(waterMark);
// 设置水印旋转角度和位置(旋转角度以弧度为单位的)
g.rotate(-degree,(double) width / 2, (double) height / 2);
g.drawString(waterMark, (width-textWidth)/2, (height-80)/2);
}
// 底部页脚文字
if (null != waterMark && !"".equals(waterMark.trim()))
{
textWidth = fm.stringWidth(footerMark);
g.rotate(degree,(double) width / 2, (double) height / 2);
g.drawString(footerMark ,(width - textWidth)/2,height-30);
}
g.dispose();
os = new FileOutputStream(targetImg);
// 重新生成图片
ImageIO.write(buffImg, postfix, os);
return targetImg;
}
catch (Exception e)
{
e.printStackTrace();
returnnull;
}
finally
{
try
{
if (null != os)
os.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
/**
* 说明:此方法需要调用dll文件,存在平台相关性,不建议项目使用,仅供学习。
* 依赖的jacob.dll文件需要放到C:\WINDOWS\system32目录下,否则无法使用
*
* word加水印号
* @param sourceFile 源文件路径
* @param targetFile 加水印号文件输出路径
* @param waterMark 水印号
* @param footerMark 页脚文字
* @return加水印号文件输出路径
* @throws Exception
*/
publicstatic String writeDocMark(String sourceFile, String targetFile, String waterMark, String footerMark)
{
// 初始化com的线程
ComThread.InitSTA();
ActiveXComponent activeX = new ActiveXComponent("word.Application");
Dispatch docs = activeX.getProperty("Documents").toDispatch();
// 设置打开的word应用程序是否可见
activeX.setProperty("Visible", new Variant(false));
Dispatch document = Dispatch.call(docs, "Open", sourceFile).toDispatch();
// 获得活动窗体对象
Dispatch activeWin = activeX.getProperty("ActiveWindow")
.toDispatch();
Dispatch activePan = Dispatch.get(activeWin, "ActivePane")
.toDispatch();
// 取得视窗对象
Dispatch view = Dispatch.get(activePan, "View").toDispatch();
// 输入页眉内容
// Dispatch.put(view, "SeekView", new Variant(9));
Dispatch fileSelection = Dispatch.get(activeX, "Selection")
.toDispatch();
// Dispatch.put(fileSelection, "Text", "页眉文字....!!");
// 页脚内容
Dispatch.put(view, "SeekView", new Variant(10));
Dispatch.put(fileSelection, "Text", footerMark);
Dispatch headfooter = Dispatch.get(fileSelection, "HeaderFooter")
.toDispatch();
// 取得图形对象
Dispatch shapes = Dispatch.get(headfooter, "Shapes").toDispatch();
// 给文档全部加上水印
Dispatch selection = Dispatch.call(shapes, "AddTextEffect",
new Variant(9), waterMark, "宋体", new Variant(1),
new Variant(false), new Variant(false), new Variant(0),
new Variant(0)).toDispatch();
Dispatch.call(selection, "Select");
// 设置水印参数
Dispatch shapeRange = Dispatch.get(fileSelection, "ShapeRange")
.toDispatch();
Dispatch.put(shapeRange, "Name", "PowerPlusWaterMarkObject1");
Dispatch textEffect = Dispatch.get(shapeRange, "TextEffect")
.toDispatch();
Dispatch.put(textEffect, "NormalizedHeight", new Boolean(false));
Dispatch line = Dispatch.get(shapeRange, "Line").toDispatch();
Dispatch.put(line, "Visible", new Boolean(false));
Dispatch fill = Dispatch.get(shapeRange, "Fill").toDispatch();
Dispatch.put(fill, "Visible", new Boolean(true));
// 设置水印透明度
Dispatch.put(fill, "Transparency", new Variant(0.2));
Dispatch foreColor = Dispatch.get(fill, "ForeColor").toDispatch();
// 设置水印颜色
Dispatch.put(foreColor, "RGB", new Variant(16711680));
Dispatch.call(fill, "Solid");
// 设置水印旋转
Dispatch.put(shapeRange, "Rotation", new Variant(315));
Dispatch.put(shapeRange, "LockAspectRatio", new Boolean(true));
Dispatch.put(shapeRange, "Height", new Variant(117.0709));
Dispatch.put(shapeRange, "Width", new Variant(468.2835));
Dispatch.put(shapeRange, "Left", new Variant(-999995));
Dispatch.put(shapeRange, "Top", new Variant(-999995));
Dispatch wrapFormat = Dispatch.get(shapeRange, "WrapFormat")
.toDispatch();
// 是否允许交叠
Dispatch.put(wrapFormat, "AllowOverlap", new Variant(false));
Dispatch.put(wrapFormat, "Side", new Variant(3));
Dispatch.put(wrapFormat, "Type", new Variant(3));
Dispatch.put(shapeRange, "RelativeHorizontalPosition", new Variant(0));
Dispatch.put(shapeRange, "RelativeVerticalPosition", new Variant(0));
Dispatch.put(view, "SeekView", new Variant(0));
if (null != document)
{
Dispatch.invoke(document, "SaveAs", Dispatch.Method, new Object[] {targetFile, new Variant(0)} , newint[1]);
Dispatch.call(document, "Close", new Variant(true));
}
if (null != activeX)
{
// 关闭word文件
activeX.invoke("Quit", new Variant[]{});
}
// 释放com线程
ComThread.Release();
return targetFile;
}
/**
* 获取文件的后缀名
*/
privatestatic String getPostfix(String inputFilePath)
{
String[] p = inputFilePath.split("\\.");
if (p.length > 0)
{
return p[p.length - 1];
}
else
{
returnnull;
}
}
}
依赖的jar包:iText-2.1.7.jar、iTextAsian.jar、jacob.jar
依赖的文件:jacob.dll