1.添加依赖
使用spire.office免费版
<repositories>
<repository>
<id>com.e-iceblue</id>
<url>https://repo.e-iceblue.cn/repository/maven-public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId> e-iceblue </groupId>
<artifactId>spire.office.free</artifactId>
<version>5.3.1</version>
</dependency>
</dependencies>
2.示例代码
代码参照网络搜索结果,部分地方需要优化:
①是否可以不使用缓存区;
②XLSX 水印位置需要调整
import com.spire.doc.*;
import com.spire.doc.FileFormat;
import com.spire.pdf.*;
import com.spire.pdf.graphics.*;
import java.awt.*;
import java.awt.geom.*;
import java.awt.geom.Dimension2D;
import java.awt.image.BufferedImage;
import com.spire.doc.documents.Paragraph;
import com.spire.doc.documents.ShapeLineStyle;
import com.spire.doc.documents.ShapeType;
import com.spire.doc.documents.WatermarkLayout;
import com.spire.doc.fields.ShapeObject;
import com.spire.pdf.graphics.PdfTilingBrush;
import com.spire.xls.ViewMode;
import com.spire.xls.Workbook;
import com.spire.xls.Worksheet;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.*;
import java.security.SecureRandom;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;
import javax.swing.*;
public class WaterMarkUtils {
/**
* 缓存区路径
*/
private static String CACHE_PATH = System.getProperty("user.dir")+"/cache/";
private static final Logger logger = LoggerFactory.getLogger(WaterMarkUtils.class);
/**
* 图片添加文字水印
* @param logoText 水印文字
* @param srcFile 原图片文件
* @param degree 旋转角度
* @param color 水印文字颜色
*/
public static MultipartFile setWaterMarkToImageByWords(MultipartFile srcFile, String logoText, Integer degree, Color color) {
InputStream is = null;
OutputStream os = null;
try {
// 1、源图片
InputStream inputImg = srcFile.getInputStream();
Image srcImg = ImageIO.read(inputImg);
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));
}
// 5、设置水印文字颜色
g.setColor(color);
// 6、设置水印文字Font
Font font = new Font("宋体", Font.BOLD, 150);
g.setFont(font);
// 7、设置水印文字透明度
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.45f));
// 8、第一参数->设置的内容,后面两个参数->文字在图片上的坐标位置(x,y)
JLabel label = new JLabel(logoText);
FontMetrics metrics = label.getFontMetrics(font);
int width = metrics.stringWidth(label.getText())+80;//文字水印的宽
int rowsNumber = buffImg.getWidth()/width;// 图片的高 除以 文字水印的宽 ——> 打印的行数(以文字水印的宽为间隔)
int columnsNumber = buffImg.getWidth()/width;//图片的宽 除以 文字水印的宽 ——> 每行打印的列数(以文字水印的宽为间隔)
for(int j=0;j<rowsNumber;j++){
for(int i=0;i<columnsNumber;i++){
g.drawString(logoText, i*width + j*width, -i*width + j*width+120);//画出水印,并设置水印位置
}
}
// 9、释放资源
g.dispose();
// 获取图片文件名 xxx.png xxx
String originFileName = srcFile.getOriginalFilename();
// 获取原图片后缀 png
int lastSplit = originFileName.lastIndexOf(".");
String suffix = originFileName.substring(lastSplit + 1);
// 获取图片原始信息
File file = new File(CACHE_PATH + srcFile.getOriginalFilename());
if (!file.getParentFile().exists()) {
logger.info("not exists");
//创建上级目录
file.getParentFile().mkdir();
}
OutputStream bs = new FileOutputStream(CACHE_PATH + srcFile.getOriginalFilename());
ImageOutputStream imOut = ImageIO.createImageOutputStream(bs);
ImageIO.write(buffImg, suffix, imOut);
// 加水印后的文件上传
srcFile = fileToMultipart(CACHE_PATH + srcFile.getOriginalFilename());
} 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();
}
}
return srcFile;
}
//============================================2、PDF添加动态文字水印==================================================
/**
* PDF添加文字水印
* @param srcPdf 上传文件
* @param logoText 水印文字
* @param degree 旋转角度
* @param color 水印文字颜色
*/
public static MultipartFile setWaterMarkToPdfByWords(MultipartFile srcPdf, String logoText, Integer degree, Color color) throws IOException {
try {
InputStream inputStream = srcPdf.getInputStream();
PdfDocument pdf = new PdfDocument();
pdf.loadFromStream(inputStream);
//加载示例文档
Font font = new Font("宋体", 24,24);
PdfTrueTypeFont pdfTrueTypeFont = new PdfTrueTypeFont(font, true);//true防止中文乱码
for (Object obj : pdf.getPages()) {
PdfPageBase page = (PdfPageBase) obj;
Dimension2D dimension2D = new Dimension();
dimension2D.setSize(page.getCanvas().getClientSize().getWidth() / 2, page.getCanvas().getClientSize().getHeight() / 3);
PdfTilingBrush brush = new PdfTilingBrush(dimension2D);
brush.getGraphics().setTransparency(0.3F);
brush.getGraphics().save();
brush.getGraphics().translateTransform((float) brush.getSize().getWidth() / 2, (float) brush.getSize().getHeight() / 2);
brush.getGraphics().rotateTransform(-45);
brush.getGraphics().drawString(logoText, pdfTrueTypeFont, PdfBrushes.getViolet(), 0, 0, new PdfStringFormat(PdfTextAlignment.Center));
brush.getGraphics().restore();
brush.getGraphics().setTransparency(1);
Rectangle2D loRect = new Rectangle2D.Float();
loRect.setFrame(new Point2D.Float(0, 0), page.getCanvas().getClientSize());
page.getCanvas().drawRectangle(brush, loRect);
}
/* pdf.saveToFile(CACHE_PATH + "2.pdf");
pdf.close();*/
//保存文档
File file = new File(CACHE_PATH + srcPdf.getOriginalFilename());
if (!file.getParentFile().exists()) {
logger.info("not exists");
//创建上级目录
file.getParentFile().mkdir();
}
//设置缓存区
pdf.saveToFile(CACHE_PATH + srcPdf.getOriginalFilename());
pdf.close();
//读取缓存区的文件
srcPdf = fileToMultipart(CACHE_PATH + srcPdf.getOriginalFilename());
} catch (Exception e) {
logger.info("pdf添加水印异常: "+e);
e.printStackTrace();
}
return srcPdf;
}
//============================================3、DOCX/DOC添加文字水印==================================================
/**
* DOCX/DOC添加文字水印
* @param srcPdf 上传文件
* @param logoText 水印文字
* @param degree 旋转角度
* @param color 水印文字颜色
*/
public static MultipartFile setWaterMarkToDocByWords( MultipartFile srcPdf, String logoText, Integer degree, Color color) {
try{
InputStream inputStream = srcPdf.getInputStream();
Document doc = new Document();
doc.loadFromStream(inputStream, FileFormat.Auto);
//添加艺术字并设置大小
ShapeObject shape = new ShapeObject(doc, ShapeType.Text_Plain_Text);
shape.setWidth(60);
shape.setHeight(20);
//设置艺术字文本内容、颜色,位置及样式
shape.setVerticalPosition(30);
shape.setHorizontalPosition(20);
shape.setRotation(315);
shape.getWordArt().setText(logoText);
shape.setFillColor(color);
shape.setLineStyle(ShapeLineStyle.Single);
shape.setStrokeColor(color);
//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 paragraph1;
for (int i = 0; i < 3; i++) {
//添加段落到页眉
paragraph1 = header.addParagraph();
for (int j = 0; j < 3; j++) {
//复制艺术字并设置多行多列位置
shape = (ShapeObject) shape.deepClone();
shape.setVerticalPosition(50 + 150 * i);
shape.setHorizontalPosition(20 + 160 * j);
paragraph1.getChildObjects().add(shape);
}
}
}
//保存文档
File file = new File(CACHE_PATH + srcPdf.getOriginalFilename());
if (!file.getParentFile().exists()) {
logger.info("not exists");
//创建上级目录
file.getParentFile().mkdir();
}
doc.saveToFile(CACHE_PATH + srcPdf.getOriginalFilename());
//读取缓存区的文件
srcPdf = fileToMultipart(CACHE_PATH + srcPdf.getOriginalFilename());
} catch (Exception e) {
logger.info("doc添加水印异常: "+e);
e.printStackTrace();
}
return srcPdf;
}
/**
* 读取缓存区的文件
* @param path 文件路径
*/
private static MultipartFile fileToMultipart(String path){
File file = new File(path);
//无参构造,文件大小最大值便是默认值10kb,超过10Kb便会通过生成临时文件转化不占用内存
FileItemFactory factory = new DiskFileItemFactory();
FileItem item = factory.createItem("textField", "text/plain", true, file.getName());
int bytesRead;
byte[] buffer = new byte[path.length()];
try (FileInputStream fis = new FileInputStream(file);
OutputStream os = item.getOutputStream()) {
while ((bytesRead = fis.read(buffer, 0, path.length())) != -1) {
os.write(buffer, 0, bytesRead);
}
} catch (IOException e) {
logger.info("文件转化失败, fileUrl: "+ file.getName());
logger.info("e: "+e);
return null;
}finally {
//操作完删除缓存区文件
file.delete();
}
return new CommonsMultipartFile(item);
}
//============================================4、XLS/XLSL添加文字水印==================================================
/**
* XLSX添加文字水印
* @param srcFile 上传文件
* @param logoText 水印文字
* @param degree 旋转角度
* @param color 水印文字颜色
*/
public static MultipartFile setWaterMarkToXlsxByWords(MultipartFile srcFile, String logoText, Integer degree, Color color){
try{
com.spire.xls.Workbook wb = new com.spire.xls.Workbook();
InputStream inputStream = srcFile.getInputStream();
wb.loadFromStream(inputStream);
//设置文本和字体大小
Font font = new Font("仿宋", Font.PLAIN, 40);
for (int i =0;i<wb.getWorksheets().getCount();i++)
{
Worksheet sheet = wb.getWorksheets().get(i);
//调用DrawText() 方法插入图片
BufferedImage imgWtrmrk = drawText(degree,logoText + " "+logoText + " "+ logoText, font, color, Color.white, sheet.getPageSetup().getPageHeight(), sheet.getPageSetup().getPageWidth());
//将图片设置为页眉
sheet.getPageSetup().setCenterHeaderImage(imgWtrmrk);
sheet.getPageSetup().setCenterHeader("&G");
//将显示模式设置为Layout
sheet.setViewMode(ViewMode.Layout);
}
//保存文档
File file = new File(CACHE_PATH + srcFile.getOriginalFilename());
if (!file.getParentFile().exists()) {
logger.info("not exists");
//创建上级目录
file.getParentFile().mkdir();
}
wb.saveToFile(CACHE_PATH + srcFile.getOriginalFilename());
//读取缓存区的文件
srcFile = fileToMultipart(CACHE_PATH + srcFile.getOriginalFilename());
}catch (Exception e){
logger.info("xlsx添加水印异常: "+e);
}
return srcFile;
}
private static BufferedImage drawText (Integer degree,String text, Font font, Color textColor, Color backColor,double height, double width)
{
//定义图片宽度和高度
BufferedImage img = new BufferedImage((int) width, (int) height, BufferedImage.TYPE_INT_ARGB);
Graphics2D loGraphic = img.createGraphics();
//获取文本size
FontMetrics loFontMetrics = loGraphic.getFontMetrics(font);
int liStrWidth = loFontMetrics.stringWidth(text);
int liStrHeight = loFontMetrics.getHeight();
//文本显示样式及位置 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(degree));
loGraphic.translate(-((int) width - liStrWidth) / 2, -((int) height - liStrHeight) / 2);
loGraphic.setFont(font);
loGraphic.setColor(textColor);
loGraphic.drawString(text, ((int) width - liStrWidth) /6 , ((int) height - liStrHeight) /6);
loGraphic.drawString(text,((int) width - liStrWidth) /3, ((int) height - liStrHeight) /3);
loGraphic.drawString(text,((int) width - liStrWidth) /2, ((int) height - liStrHeight) /2);
loGraphic.dispose();
return img;
}
public static String getCharAndNumr(int length) {
SecureRandom random = new SecureRandom();
StringBuffer valSb = new StringBuffer();
String charStr = "0123456789";
int charLength = charStr.length();
for (int i = 0; i < length; i++) {
int index = random.nextInt(charLength);
valSb.append(charStr.charAt(index));
}
return valSb.toString();
}
}
参考:https://blog.csdn.net/u011293064/article/details/115730903等
版权声明:本文为m0_71366343原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。