poi导出excel加水印,单元格可修改 java 下载生成Excel文件添加水印
原文链接:https://blog.csdn.net/weixin_40077255/article/details/112848376
目录
poi导出excel加水印,单元格可修改(只支持XSSFWorkbook)
poi导出excel加水印,单元格可修改(只支持XSSFWorkbook)
引入的jar包:
<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.4</version>
</dependency>
操作水印的工具类:
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.Workbook;
import org.apache.poi.xssf.usermodel.XSSFRelation;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
/**
* <p>Title: 水印设置 </p>
* <p>Description: 水印设置 </p>
*/
public class WatermarkUtils {
private final static Logger logger = LoggerFactory.getLogger(WatermarkUtils.class);
static class FontImage {
final static String[] TEXT = new String[]{"XXXX系统"};
final static Integer fontSize = 12;
/**
* <p>Title: 设置水印相关信息 </p>
* <p>Description: 水印信息 </p>
*/
static class Watermark {
private Boolean enable;
private String[] text;
private String dateFormat;
private String color;
public Watermark() {}
public Watermark(Boolean enable, String[] text, String dateFormat, String color) {
this.enable = enable;
this.text = text;
this.dateFormat = dateFormat;
this.color = color;
}
public Boolean getEnable() {
return enable;
}
public void setEnable(Boolean enable) {
this.enable = enable;
}
public String[] getText() {
return text;
}
public void setText(String[] text) {
this.text = text;
}
public String getDateFormat() {
return dateFormat;
}
public void setDateFormat(String dateFormat) {
this.dateFormat = dateFormat;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
}
/**
* <p>Title: 生成水印图片信息 </p>
* <p>Description: 生成水印图片信息 </p>
*/
public static BufferedImage createWatermarkImage(Watermark watermark) {
if (watermark == null) {
watermark = new Watermark();
watermark.setEnable(true);
watermark.setText(TEXT);
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 (watermark.getText().length==0) {
watermark.setText(TEXT);
}
if (StringUtils.isEmpty(watermark.getColor())) {
watermark.setColor("#C5CBCF");
}
}
Font font = new Font("微软雅黑", Font.BOLD, fontSize);
Integer width = 300;
Integer height = 100 * watermark.getText().length;
// 设置最大的宽度
for (int j=0;j<watermark.getText().length;j++){
int textWidth = fontSize*watermark.getText()[j].length();
if(textWidth>width){
width=textWidth;
}
}
height=(width/2);
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, -0.3);
// 消除文字锯齿
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
//设置字体平滑
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
int y =(height/2)+font.getSize()*2;
int x =0;
for (int j=0;j<watermark.getText().length;j++){
String[] textArray = watermark.getText()[j].split("\n");
y+= 1*(j+1);
// 计算文字长度,计算居中的x点坐标
FontMetrics fm = g.getFontMetrics(font);
int textWidth = fm.stringWidth(watermark.getText()[j]);
x = (width - textWidth) / 2;
for (int i = 0; i < textArray.length; i++) {
// 画出字符串
g.drawString(textArray[i], x, y);
y = y + font.getSize();
}
}
g.dispose();// 释放画笔
return image;
}
}
/**
* <p>Title: 添加水印 </p>
* <p>Description: 添加水印信息 </p>
* @param wb 工作薄
* @param sheet 工作表
* @param waterMark 水印信息
*/
public static void addWaterMark(XSSFWorkbook wb, XSSFSheet sheet, String waterMark){
//是否添加水印
if(StringUtils.isEmpty(waterMark)){
FontImage.Watermark watermark = new FontImage.Watermark();
watermark.setText(new String[]{waterMark});
watermark.setEnable(true);
BufferedImage image = FontImage.createWatermarkImage(watermark);
// 导出到字节流B
ByteArrayOutputStream os = new ByteArrayOutputStream();
try {
ImageIO.write(image, "png", os);
} catch (IOException e) {
logger.error("add watermark error: {}", e.getMessage());
}
int pictureIdx = wb.addPicture(os.toByteArray(), Workbook.PICTURE_TYPE_PNG);
POIXMLDocumentPart poixmlDocumentPart = wb.getAllPictures().get(pictureIdx);
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());
}
}
/**
* <p>Title: 添加水印 </p>
* <p>Description: 添加水印信息 </p>
* @param wb 工作薄
* @param sheet 工作表
* @param waterMarks 水印信息
*/
public static void addWaterMarks(XSSFWorkbook wb, XSSFSheet sheet, String[] waterMarks){
// 是否添加水印
if(waterMarks!=null && waterMarks.length>0){
FontImage.Watermark watermark = new FontImage.Watermark();
watermark.setText(waterMarks);
watermark.setEnable(true);
BufferedImage image = FontImage.createWatermarkImage(watermark);
// 导出到字节流B
ByteArrayOutputStream os = new ByteArrayOutputStream();
try {
ImageIO.write(image, "png", os);
} catch (IOException e) {
logger.error("add watermark error: {}", e.getMessage());
}
int pictureIdx = wb.addPicture(os.toByteArray(), Workbook.PICTURE_TYPE_PNG);
POIXMLDocumentPart poixmlDocumentPart = wb.getAllPictures().get(pictureIdx);
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());
}
}
/**
* <p>Title: 添加水印 </p>
* <p>Description: 添加水印 </p>
* @param workbook 工作薄
* @param waterMark 水印信息
*/
public static void addWorkbookWaterMark(Workbook workbook, String waterMark){
if (workbook != null){
XSSFWorkbook xssfWorkbook = (XSSFWorkbook)workbook;
for(int i = 0; i < xssfWorkbook.getNumberOfSheets(); i++){
addWaterMark(xssfWorkbook, xssfWorkbook.getSheetAt(i),waterMark);
}
}
}
/**
* <p>Title: 添加水印 </p>
* <p>Description: 添加水印 </p>
* @param workbook 工作薄
* @param waterMarks 水印信息
*/
public static void addWorkbookWaterMarks(Workbook workbook, String[] waterMarks){
if (workbook != null){
XSSFWorkbook xssfWorkbook = (XSSFWorkbook)workbook;
for(int i = 0; i < xssfWorkbook.getNumberOfSheets(); i++){
addWaterMarks(xssfWorkbook, xssfWorkbook.getSheetAt(i), waterMarks);
}
}
}
public static void main(String[] args){
try {
XSSFWorkbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("0");
Sheet sheet1 = workbook.createSheet("1");
// 水印信息
String[] waterMarks = {"XXX系统", DateUtils.getDate("yyyy-MM-dd HH:ss")};
WatermarkUtils.addWorkbookWaterMarks(workbook, waterMarks);
FileOutputStream fileOut = new FileOutputStream("C:\\Users\\rong\\Desktop\\123.xlsx");
workbook.write(fileOut);
fileOut.close();
fileOut.flush();
} catch(Exception e) {
e.printStackTrace();
}
}
}
最终效果
小提示
1、如果需要导出.xls文件,建议创建XSSFWorkbook,添加水印后,输出时修改文件后缀。
2、大批量数据情况下注意HSSFWorkbook数据区域,防止修改后缀导致数据丢失。
3、此方法弊端,打印无法显示水印信息,如需要打印显示水印,请选择图片方式进行添加水印。
标签:
java
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)