excel表生成截图并添加水印

导包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.xmlbeans</groupId>
<artifactId>xmlbeans</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.4</version>
</dependency>

实现代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
public static void main(String[] args) {
// Excel文件的路径,需根据实际情况进行替换
String excelFilePath = "F:\\info.xlsx";
// 生成的图片文件的路径,同样需根据实际情况指定
String imageFilePath = "F:\\image.png";

try (FileInputStream fis = new FileInputStream(new File(excelFilePath));
// 使用Apache POI的XSSFWorkbook来读取Excel文件,这里假设文件是.xlsx格式
Workbook workbook = new XSSFWorkbook(fis)) {

// 获取Excel文件中的第一个工作表,可根据需求调整获取的工作表
Sheet sheet = workbook.getSheetAt(0);
// 计算工作表中的行数,因为getLastRowNum()获取的是最后一行的索引(从0开始),所以要加1得到实际行数
int rowCount = sheet.getLastRowNum() + 1;
int columnCount = 0;

// 确定工作表中的列数,遍历每一行,找到拥有最多单元格的那一行,其单元格数量就是列数
for (Row row : sheet) {
if (row != null && row.getLastCellNum() > columnCount) {
columnCount = row.getLastCellNum();
}
}

// 创建一个BufferedImage对象用于承载Excel文件的内容,其宽度和高度根据列数、行数以及每个单元格的预设宽度、高度来确定
int cellWidth = 100; // 根据需要调整每个单元格的宽度
int cellHeight = 30; // 根据需要调整每个单元格的高度
BufferedImage image = new BufferedImage(columnCount * cellWidth, rowCount * cellHeight, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = image.createGraphics();

// 设置背景颜色,这里将整个图片的背景设置为白色
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, image.getWidth(), image.getHeight());

// 绘制单元格边框和内容,先设置绘制颜色为黑色
g2d.setColor(Color.BLACK);
// 循环遍历每一行
for (int rowIndex = 0; rowIndex < rowCount; rowIndex++) {
Row row = sheet.getRow(rowIndex);
// 检查行是否存在
if (row == null) {
continue;
}
// 循环遍历每一列
for (int colIndex = 0; colIndex < columnCount; colIndex++) {
Cell cell = row.getCell(colIndex);
String cellValue = getCellValue(cell);

// 绘制单元格边框,根据当前单元格所在的列和行的位置以及单元格的宽度、高度来绘制矩形边框
g2d.drawRect(colIndex * cellWidth, rowIndex * cellHeight, cellWidth, cellHeight);

// 绘制单元格内容,将单元格中的文本内容绘制到对应单元格的合适位置(这里是距离左边框5像素,距离上边框20像素的位置)
g2d.drawString(cellValue, colIndex * cellWidth + 5, rowIndex * cellHeight + 20);
}
}

// 绘制水印
drawWatermark(g2d, image.getWidth(), image.getHeight());

// 保存图片,将绘制好内容的BufferedImage对象以PNG格式保存到指定的文件路径下
ImageIO.write(image, "png", new File(imageFilePath));

g2d.dispose();
// 在控制台输出提示信息,表示Excel文件已成功转换为图片
System.out.println("Excel文件已成功转换为图片。");

} catch (IOException e) {
// 如果出现IO异常,打印异常堆栈信息,方便排查问题
e.printStackTrace();
}
}

// 该方法用于获取单元格中的值,并根据单元格不同的数据类型进行相应的处理,返回字符串形式的值
private static String getCellValue(Cell cell) {
if (cell == null) {
return "";
}
switch (cell.getCellType()) {
case STRING:
return cell.getStringCellValue();
case NUMERIC:
return String.valueOf(cell.getNumericCellValue());
case BOOLEAN:
return String.valueOf(cell.getBooleanCellValue());
case FORMULA:
return cell.getCellFormula();
default:
return "";
}
}

// 该方法用于在图像上绘制水印
private static void drawWatermark(Graphics2D g2d, int width, int height) {
// 设置字体和颜色,这里使用了半透明的红色
g2d.setFont(new Font("宋体", Font.BOLD, 24)); // 使用系统自带的中文字体
g2d.setColor(new Color(255, 0, 0, 128)); // 半透明红色

// 定义水印文本
String watermarkText = "水印";

// 获取文本的尺寸
FontMetrics metrics = g2d.getFontMetrics();
int textWidth = metrics.stringWidth(watermarkText);
int textHeight = metrics.getHeight();

// 定义倾斜角度(弧度)
double angle = Math.toRadians(-20); // 逆时针旋转20度

// 定义水印之间的间距
int spacing = 150;

// 循环绘制水印
for (int x = -textWidth; x < width; x += spacing) {
for (int y = -textHeight; y < height; y += spacing) {
AffineTransform originalTransform = g2d.getTransform();
g2d.translate(x + textWidth / 2, y + textHeight / 2);
g2d.rotate(angle);
g2d.drawString(watermarkText, -textWidth / 2, -textHeight / 2);
g2d.setTransform(originalTransform);
}
}
}

效果

注:我excel对比上一篇文章添加过数据,数据量太少,水印间隔太远导致不显示了,我懒得改代码了

图片