网络上充斥着各种为excel添加水印的方法,但是多数效果不敢恭维,这里介绍两种添加excel水印的方法,最终实现的效果跟excel工具添加的水印无异,个人比较喜欢比较推荐。
这里说是两种,其实原理是一种,只不过因为poi的版本高低不同,导致了我们的操作发生了变化,大家可以根据自己的poi版本对应选择不同的实现方法。
这两种方法应用的时候是比较久之前了,最近想起来整理一下,可能文章中会有错误,还请口下饶人,有问题我会及时讨论更正。
关于转载说明:
第一种POI比较老的版本中,水印图片绑定参考的资料只记得是一个外国网站,因为时间久远,记不得原始链接了,还请见谅。水印生成工具类参考的是哪个网站也记不清了,求原谅。
第二种是在改造开源项目的时候发现第一种没办法用的情况下借鉴的他人资料,参考的地址为:
https://www.iflym/index.php/code/201412280001.html
跟原文有无区别记不太清了,印象里是有改造过,但是终究是借鉴了这篇帖子无疑。
效果图:
水印不会影响到文本的编辑,是真水印,不是重复贴图做成的水印。
生成水印图片的类,两种方法都会用到该类
public class FontImage {
@Data
public static class Watermark {
private Boolean enable;
private String text;
private String dateFormat;
private String color;
}
public static BufferedImage createWatermarkImage(Watermark watermark) {
if (watermark == null) {
watermark = new FontImage.Watermark();
watermark.setEnable(true);
// watermark.setText("userName");
watermark.setText("内部资料");
watermark.setColor("#C5CBCF");
watermark.setDateFormat("yyyy-MM-dd HH:mm");
} 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("microsoft-yahei", Font.PLAIN, 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(DateUtils.getNowDateFormatCustom(watermark.getDateFormat()), 0, y);// 画出字符串
g.dispose();// 释放画笔
return image;
}
}
第一种,基于POI的老版本
pom文件中添加以下依赖
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.17</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.17</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>3.14</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>ooxml-schemas</artifactId>
<version>1.0</version>
</dependency>
java核心代码
try {
XSSFWorkbook workbook = new XSSFWorkbook();
FileOutputStream out = new FileOutputStream("/Users/Tony/Downloads/out.xls");
XSSFSheet sheet = workbook.createSheet("Sheet1");
workbook.getSheet("Sheet1");
//add picture data to this workbook.
// FileInputStream is = new FileInputStream("/Users/Tony/Downloads/data_image.png");
// byte[] bytes = IOUtils.toByteArray(is);
BufferedImage image = FontImage.createBufferedImage("科技有限公司", new Font("microsoft-yahei", Font.PLAIN, 20), 300, 100, true);
// 导出到字节流B
ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageIO.write(image, "png", os);
int pictureIdx = workbook.addPicture(os.toByteArray(), Workbook.PICTURE_TYPE_PNG);
// is.close();
//add relation from sheet to the picture data
String rID = sheet.addRelation(null, XSSFRelation.IMAGES, workbook.getAllPictures().get(pictureIdx)).getRelationship().getId();
//set background picture to sheet
sheet.getCTWorksheet().addNewPicture().setId(rID);
workbook.write(out);
} catch (Exception e) {
e.printStackTrace();
}
第二种,基于POI的高版本
pom文件中添加以下依赖
(该方法中用不用的到ooxml-schemas依赖记不清了,可以删除尝试下)
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.9</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>
java核心代码
BufferedImage image = FontImage.createBufferedImage("科技有限公司", new Font("microsoft-yahei", Font.PLAIN, 20), 300, 100, true);
// 导出到字节流B
ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageIO.write(image, "png", os);
XSSFWorkbook workbook = new XSSFWorkbook(is);
int pictureIdx = workbook.addPicture(os.toByteArray(), Workbook.PICTURE_TYPE_PNG);
POIXMLDocumentPart poixmlDocumentPart = workbook.getAllPictures().get(pictureIdx);
for (int i = 0; i < workbook.getNumberOfSheets(); i++) {//获取每个Sheet表
XSSFSheet sheet = workbook.getSheetAt(i);
PackagePartName ppn = poixmlDocumentPart.getPackagePart().getPartName();
String relType = XSSFRelation.IMAGES.getRelation();
//add relation from sheet to the picture data
PackageRelationship pr = sheet.getPackagePart().addRelationship(ppn, TargetMode.INTERNAL, relType, null);
//set background picture to sheet
sheet.getCTWorksheet().addNewPicture().setId(pr.getId());
}
workbook.write(response.getOutputStream());
更多推荐
java POI为excel添加水印
发布评论