今天公司让给pdf、word、excel文件添加水印,
在网上导了一堆,最后总结了一下方法。
/**
* @author CArom_XUE 2021-03-18
*
* TODO 生成文件水印
*/
public class WatermarkUtil {
/**
* 水印每个字体的宽度为10
*/
private final static int WATERMARK_FONT_WIDTH = 6;
/**
* 水印每个字体的高度为16
*/
private final static int WATERMARK_FONT_HEIGHT = 14;
/**
* 水印图片的默认高度为20
*/
private final static double WATERMARK_IMG_HEIGHT = 20d;
/**
* 水印倾斜角度 默认是50 为保证文字连续性尽量不要修改
*/
private final static int WATERMARK_FONT_ROTATION = 50;
/**
* 水印字体颜色
*/
private static Color watermark_color = new Color(190,190,190);
/**
* 给word文件加载水印
* @param realPath 原文件路径
* @param newPath 加水印文件路径
* @param content 水印内容
* @author CArom_XUE 2021-03-18
*/
public static void addWordWaterMark(String realPath, String newPath, String content) {
com.aspose.words.Document document;
try {
System.out.println("----Carom_Debugging---addWordWaterMark----into");
System.out.println("----Carom_Debugging---newPath----"+newPath);
System.out.println("----Carom_Debugging---content----"+content);
System.out.println("-------------fileVO.getRealPath()==="+realPath);
document = new com.aspose.words.Document(realPath);
WatermarkUtil.insertWatermarkText(document, content); //调用工具类方法,txt是水印文字
//document.protect(ProtectionType.READ_ONLY); //设置只读,其实我用着没效果
document.save(newPath); //最后必须保存
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 为word文档插入文本水印
*
* @param doc 文档对象
* @param watermarkText 文本内容
* @throws Exception
* @author CArom_XUE 2021-03-18
*/
private static void insertWatermarkText(com.aspose.words.Document doc, String watermarkText) throws Exception {
if (null== watermarkText || "".equals(watermarkText)) {
System.out.println("没有配置水印内容, 无法为文档加入水印");
return;
}
com.aspose.words.Paragraph watermarkPara = new com.aspose.words.Paragraph(doc);
// TODO 这里的数据 计算水印个数(900 150 700 150) 首个水印位置(-200至-100)都是实验得到 没有理论依据
for (int top = 0; top < 900; top += 300) {
int max=-200,min=-400;
int beginLeft =(int) (Math.random()*(max-min)+min);
// int beginLeft = new Random().ints(-400, -200).limit(1).findFirst().getAsInt();
for (int left = beginLeft; left < 700; left += 300) {
// 如果是左起第一个水印则通过字符串截取达到随机显示水印的目的
// 这样做的原因为了保证倾斜的行保证对齐 又能表现随机的特性 不是好办法
if (left == beginLeft) {
//int splitNo = new Random().ints(0, watermarkText.length()).limit(1).findFirst().getAsInt();
Random random = new Random();
int splitNo = random.nextInt(watermarkText.length());
String firstWater = watermarkText.substring(splitNo) + " ".substring(0, splitNo);
Shape waterShape = buildTextShape(doc, firstWater, left, top);
watermarkPara.appendChild(waterShape);
} else {
Shape waterShape = buildTextShape(doc, watermarkText, left, top);
watermarkPara.appendChild(waterShape);
}
}
}
// 在每个部分中,最多可以有三个不同的标题,因为我们想要出现在所有页面上的水印,插入到所有标题中。
for (int n = 0; n < doc.getSections().getCount(); n++) {
Section sect = doc.getSections().get(n);
// 每个区段可能有多达三个不同的标题,因为我们希望所有页面上都有水印,将所有的头插入。
insertWatermarkIntoHeader(watermarkPara, sect, HeaderFooterType.HEADER_PRIMARY);
insertWatermarkIntoHeader(watermarkPara, sect, HeaderFooterType.HEADER_FIRST);
insertWatermarkIntoHeader(watermarkPara, sect, HeaderFooterType.HEADER_EVEN);
} }
/**
* 构建文字shape类
*
* @param doc 文档对象
* @param watermarkText 水印文字
* @param left 左边距
* @param top 上边距
* @throws Exception
* @author CArom_XUE 2021-03-18
*/
private static Shape buildTextShape(com.aspose.words.Document doc, String watermarkText, double left, double top) throws Exception {
Shape watermark = new Shape(doc, com.aspose.words.ShapeType.TEXT_PLAIN_TEXT);
watermark.getTextPath().setText(watermarkText);
watermark.getTextPath().setFontFamily("仿宋");
watermark.setWidth(watermarkText.length() * (double)WATERMARK_FONT_WIDTH);
watermark.setHeight(WATERMARK_FONT_HEIGHT*3);
watermark.setRotation(WATERMARK_FONT_ROTATION);
//绘制水印颜色
watermark.getFill().setColor(watermark_color);
watermark.setStrokeColor(watermark_color);
//将水印放置在页面中心
watermark.setLeft(left);
watermark.setTop(top);
watermark.setWrapType(WrapType.NONE);
return watermark;
} /**
* 插入水印
*
* @param watermarkPara 水印段落
* @param sect 部件
* @param headerType 头标类型字段
* @throws Exception
* @author CArom_XUE 2021-03-18
*/
private static void insertWatermarkIntoHeader(com.aspose.words.Paragraph watermarkPara, com.aspose.words.Section sect, int headerType) throws Exception {
com.aspose.words.HeaderFooter header = sect.getHeadersFooters().getByHeaderFooterType(headerType);
if (header == null) {
header = new com.aspose.words.HeaderFooter(sect.getDocument(), headerType);
sect.getHeadersFooters().add(header);
}
header.appendChild(watermarkPara.deepClone(true));
}
/**
* 给PDF文件加载水印
* @param realPath 原文件路径
* @param newPath 加水印文件路径
* @param content 水印内容
* @author CArom_XUE 2021-03-18
*/
public static void addPdfWatermark(String realPath, String newPath, String watermark) {
try {
//创建PdfDocument对象
PdfDocument pdf = new PdfDocument(); //加载示例文档
pdf.loadFromFile(realPath);
Font font = new Font("仿宋", Font.PLAIN, 40);
//遍历页数
for (int i = 0; i < pdf.getPages().getCount();i++)
{
PdfPageBase page = pdf.getPages().get(i); insertPdfWatermark(page,watermark);
}
//保存文档
pdf.saveToFile(newPath);
pdf.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 给PDF加载水印
* @param page PDF当前页
* @param watermark 水印内容
* CArom_XUE 2021-03-18
*/
private static void insertPdfWatermark(PdfPageBase page, String watermark) {
Dimension2D dimension2D = new Dimension ();
//设置字体
PdfTrueTypeFont font1 = new PdfTrueTypeFont(new Font ("仿宋", Font.PLAIN, 14), true);
//PdfTrueTypeFont font1 = new PdfTrueTypeFont ( new Font ("Arial Unicode MS",Font.PLAIN, 36),true );
//水印数量
dimension2D.setSize(page.getCanvas().getClientSize().getWidth() / 2, page.getCanvas().getClientSize().getHeight() / 3);
PdfTilingBrush brush = new PdfTilingBrush (dimension2D);
//透明度
brush.getGraphics().setTransparency(0.4F);
brush.getGraphics().save();
//浮动
brush.getGraphics().translateTransform((float) brush.getSize().getWidth() / 5, (float) brush.getSize().getHeight() / 5);
//倾斜度(负:上倾斜,正:下倾斜)
brush.getGraphics().rotateTransform(-45);
//设置字体颜色
PdfBrush brush_color = new PdfSolidBrush(new PdfRGBColor(new Color(220,220,220)));
//水印内容和水印坐标
brush.getGraphics().drawString(watermark, font1, brush_color, 25 , 30 , new PdfStringFormat (PdfTextAlignment.Center));
brush.getGraphics().restore();
brush.getGraphics().setTransparency(1);
//yi
Rectangle2D loRect = new Rectangle2D.Float();
loRect.setFrame(new Point2D.Float(0, 0), page.getCanvas().getClientSize()); page.getCanvas().drawRectangle(brush, loRect);
}
/**
* 给表格文件添加水印
* @param realPath 原文件路径
* @param newPath 加水印文件路径
* @param content 水印内容
* @author CArom_XUE 2021-03-18
*/
public static void addExcelWaterMark(String realPath, String newPath, String content) {
//Initialize a new instance of workbook and load the test file
System.out.println("----Carom_Debugging---addExcelWaterMark----into");
System.out.println("----Carom_Debugging---newPath----"+newPath);
System.out.println("----Carom_Debugging---content----"+content);
try {
Workbook workbook = new Workbook();
workbook.loadFromFile(realPath);
//设置字体
Font font = new Font("仿宋", Font.PLAIN, 30);
String watermark = content;
for (Iterator iter = workbook.getWorksheets().iterator(); iter
.hasNext();) {
Worksheet sheet= (Worksheet) iter.next();
//加载图片
Color watermark_color = new Color(0,0,0);
BufferedImage imgWtrmrk = drawText(watermark, font, Color.gray,Color.WHITE, sheet.getPageSetup().getPageHeight(), sheet.getPageSetup().getPageWidth());
//设置页眉
sheet.getPageSetup().setLeftHeaderImage(imgWtrmrk);
sheet.getPageSetup().setRightHeaderImage(imgWtrmrk);
//设置页脚
sheet.getPageSetup().setLeftFooterImage(imgWtrmrk);
sheet.getPageSetup().setRightFooterImage(imgWtrmrk);
sheet.getPageSetup().setLeftHeader("&G");
sheet.getPageSetup().setRightHeader("&G");
//sheet.getPageSetup().setRightFooter("&G");
// sheet.getPageSetup().setLeftFooter("&G");
//设置样式
sheet.setViewMode(ViewMode.Layout);
sheet.setZoom(75);//缩放比例
}
//保存文件
workbook.saveToFile(newPath, ExcelVersion.Version2013);
workbook.dispose();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
private static BufferedImage drawText (String text, Font font, Color textColor, Color backColor,double height, double width)
{
//define the width and height of image
BufferedImage img = new BufferedImage((int) width, (int) height, 2);
Graphics2D loGraphic = img.createGraphics();
//set the font size
FontMetrics loFontMetrics = loGraphic.getFontMetrics(font);
int liStrWidth = loFontMetrics.stringWidth(text);
int liStrHeight = loFontMetrics.getHeight();
//set the text format
loGraphic.setColor(backColor);
loGraphic.fillRect(0, 0, (int) width, (int) height);
loGraphic.translate(((int) width - liStrWidth) / 2, ((int) height - liStrHeight) / 2);
loGraphic.rotate(Math.toRadians(-45));
loGraphic.translate(-((int) width - liStrWidth) / 2, -((int) height - liStrHeight) / 2);
loGraphic.setFont(font);
loGraphic.setColor(textColor);
loGraphic.drawString(text, ((int) width - liStrWidth) / 2, ((int) height - liStrHeight) / 2);
loGraphic.dispose();
return img;
}
/*************以下是利用******Spire.Doc for Java*************************/
private static void addWordWatermark(String realPath,String newPath, String watermark){ com.spire.doc.Document document = new com.spire.doc.Document();
document.loadFromFile(realPath);
for (Iterator iter = document.getSections().iterator(); iter
.hasNext();) {
com.spire.doc.Section section = (com.spire.doc.Section) iter.next();
insertTextWatermark(section,watermark);
}
document.saveToFile(newPath,com.spire.doc.FileFormat.Docx );
}
private static void insertTextWatermark(com.spire.doc.Section section,String watermark ) {
TextWatermark txtWatermark = new TextWatermark();
txtWatermark.setText(watermark);
txtWatermark.setFontSize(40);
txtWatermark.setColor(Color.red);
txtWatermark.setLayout(WatermarkLayout.Diagonal);
section.getDocument().setWatermark(txtWatermark);
}
}
所需要的源码以及jar包在我的资源处可以下载,
找方法花了一点时间,调试花了一点时间,所以。。。