van@duduladudu
Excel使用apache poi 添加水印图片
工作中需要为excel添加水印图片,大概分为两种方式
1、使用java Graphics2D来创建图片,插入excel文件背景图中
2、使用已有的图片,插入到excel文件到背景图中国呢
代码如下
import java.io.*;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.openxml4j.opc.PackagePartName;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.openxml4j.opc.TargetMode;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFRelation;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class TestAddWaterStamp {
public static void main(String[] args) {
String sourceImagePath = "/Users/xxx/Desktop/2.png";
try {
//创建一个图片流,水印图片可以用现有图片,也可以用java Graphics2D来创建
//使用java创建水印图片
FontImage.Watermark watermark = new FontImage.Watermark("xxx资产","yyyy-MM-dd HH:mm","#C5CBCF",true);
BufferedImage image = FontImage.createWatermarkImage(watermark);
//使用已有的图片
BufferedImage image2 = ImageIO.read(new File(sourceImagePath));
// 导出到字节流B
ByteArrayOutputStream os = new ByteArrayOutputStream();
ByteArrayOutputStream os2 = new ByteArrayOutputStream();
ImageIO.write(image, "png", os);
ImageIO.write(image2, "png", os2);
// 创建工作簿对象
XSSFWorkbook workbook = new XSSFWorkbook(); // 或者使用 HSSFWorkbook for .xls 格式
FileOutputStream out = new FileOutputStream("/Users/xxx/Desktop/testexcel.xlsx");
String relType = XSSFRelation.IMAGES.getRelation();
//使用java绘制图片的excel展示
XSSFSheet sheet = workbook.createSheet("sheet1");
//创建图片和excel表格的数据关联
int pictureIdx = workbook.addPicture(os.toByteArray(), Workbook.PICTURE_TYPE_PNG);
POIXMLDocumentPart poixmlDocumentPart = workbook.getAllPictures().get(pictureIdx);
PackagePartName ppn = poixmlDocumentPart.getPackagePart().getPartName();
PackageRelationship pr = sheet.getPackagePart().addRelationship(ppn, TargetMode.INTERNAL, relType, null);
//设置背景图片
sheet.getCTWorksheet().addNewPicture().setId(pr.getId());
//使用已有图片的excel展示
XSSFSheet sheet2 = workbook.createSheet("sheet2");
int pictureIdx2 = workbook.addPicture(os2.toByteArray(), Workbook.PICTURE_TYPE_PNG);
POIXMLDocumentPart poixmlDocumentPart2 = workbook.getAllPictures().get(pictureIdx2);
PackagePartName ppn2 = poixmlDocumentPart2.getPackagePart().getPartName();
PackageRelationship pr2 = sheet2.getPackagePart().addRelationship(ppn2, TargetMode.INTERNAL, relType, null);
sheet2.getCTWorksheet().addNewPicture().setId(pr2.getId());
//TODO 为所有sheet添加水印图片,可以使用循环调用的方式处理
// 保存Excel文件
FileOutputStream fileOut = new FileOutputStream("/Users/xxx/Desktop/testexcel2.xlsx");
workbook.write(fileOut);
fileOut.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
import lombok.Data;
import org.springframework.util.StringUtils;
import java.awt.*;
import java.awt.image.BufferedImage;
public class FontImage {
@Data
public static class Watermark {
private Boolean enable;
private String text;
private String dateFormat;
private String color;
public Watermark(String text,String dateFormat,String color,Boolean enable){
this.text = text;
this.dateFormat = dateFormat;
this.color = color;
this.enable = enable;
}
}
public static BufferedImage createWatermarkImage(Watermark watermark) {
if (watermark == null) {
watermark = new FontImage.Watermark("内部资料","yyyy-MM-dd HH:mm","#C5CBCF",true);
} else {
if (StringUtils.isEmpty(watermark.getDateFormat())) {
watermark.setDateFormat("yyyy-MM-dd HH:mm");
} else if (watermark.getDateFormat().length() == 16) {
watermark.setDateFormat("yyyy-MM-dd HH:mm");
} else if (watermark.getDateFormat().length() == 10) {
watermark.setDateFormat("yyyy-MM-dd");
}
if (StringUtils.isEmpty(watermark.getText())) {
watermark.setText("内部资料");
}
if (StringUtils.isEmpty(watermark.getColor())) {
watermark.setColor("#C5CBCF");
}
}
String[] textArray = watermark.getText().split("\n");
Font font = new Font("Serif", Font.ITALIC, 20);
Integer width = 300;
Integer height = 100;
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
// 背景透明 开始
Graphics2D g = image.createGraphics();
image = g.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT);
g.dispose();
// 背景透明 结束
g = image.createGraphics();
g.setColor(new Color(Integer.parseInt(watermark.getColor().substring(1), 16)));// 设定画笔颜色
g.setFont(font);// 设置画笔字体
g.shear(0.1, -0.26);// 设定倾斜度
// 设置字体平滑
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
int y = 50;
for (int i = 0; i < textArray.length; i++) {
g.drawString(textArray[i], 0, y);// 画出字符串
y = y + font.getSize();
}
g.drawString("2333333", 0, y);// 画出字符串
g.dispose();// 释放画笔
return image;
}
}
pom依赖
<dependency>
<groupId>cn.afterturn</groupId>
<artifactId>easypoi-spring-boot-starter</artifactId>
<version>4.3.0</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.9</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>ooxml-schemas</artifactId>
<version>1.0</version>
</dependency>
本文参考以下文章:
1、java POI为excel添加水印
2、apache poi 官方文档
其中有问chatgpt但给到的答案无法满足水印的需求。