POI导出 Excel 加水印支持 SXSSFWorkbook 和 XSSFWorkbook 模式
文章目录
- 前言
- 一、导入maven依赖
- 二、工具类
- 三、如何使用
- 四、总结
- 五、参考
前言
最近要完成 Excel 导出添加水印,但是查了一圈一般导出只支持 XSSFWorkbook ,没有支持 SXSSFWorkbook 的,接下来我要完成导出 Excel SXSSFWorkbook 和 XSSFWorkbook 模式添加水印
效果图
一、导入maven依赖
<!--POI 相关依赖 start --><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.16</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>3.16</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml-schemas</artifactId><version>3.16</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>ooxml-schemas</artifactId><version>1.4</version></dependency><!--POI 相关依赖 end --><!--hutool 工具类 --><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>4.5.11</version></dependency>
hutool 工具类主要是用到里面的反射工具类,大家自己写反射就可以不用这个工具包。
二、工具类
代码如下:
package 你的包;import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ReflectUtil;
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.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.*;import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Date;/*** Excel 添加水印。支持 SXSSFWorkbook 和 XSSFWorkbook 模式** @author Kim Jong-un* @since 2022-01-17*/
public class WaterMarkUtil {/*** Excel 导出添加水印** @param workbook ExcelWorkbook*/public static void insertWaterMarkTextToXlsx(Workbook workbook) throws IOException {String sysName = "朝鲜合众国运营平台"; //系统名称String userName = "金正恩"; //导出人String date = DateUtil.format(new Date(), DatePattern.NORM_DATE_PATTERN); //yyyy-MM-ddString waterMarkText = sysName + "\n" + userName + " " + date;if (workbook instanceof SXSSFWorkbook) {insertWaterMarkTextToXlsx((SXSSFWorkbook) workbook, waterMarkText);} else if (workbook instanceof XSSFWorkbook) {insertWaterMarkTextToXlsx((XSSFWorkbook) workbook, waterMarkText);}//throw new RemoteException("HSSFWorkbook 模式不支持 Excel 水印");}/*** 给 Excel 添加水印** @param workbook SXSSFWorkbook* @param waterMarkText 水印文字内容*/public static void insertWaterMarkTextToXlsx(SXSSFWorkbook workbook, String waterMarkText) throws IOException {BufferedImage image = createWatermarkImage(waterMarkText);ByteArrayOutputStream imageOs = new ByteArrayOutputStream();ImageIO.write(image, "png", imageOs);int pictureIdx = workbook.addPicture(imageOs.toByteArray(), XSSFWorkbook.PICTURE_TYPE_PNG);XSSFPictureData pictureData = (XSSFPictureData) workbook.getAllPictures().get(pictureIdx);for (int i = 0; i < workbook.getNumberOfSheets(); i++) {//获取每个Sheet表SXSSFSheet sheet = workbook.getSheetAt(i);//这里由于 SXSSFSheet 没有 getCTWorksheet() 方法,通过反射取出 _sh 属性XSSFSheet shReflect = (XSSFSheet) ReflectUtil.getFieldValue(sheet, "_sh");PackagePartName ppn = pictureData.getPackagePart().getPartName();String relType = XSSFRelation.IMAGES.getRelation();PackageRelationship pr = shReflect.getPackagePart().addRelationship(ppn, TargetMode.INTERNAL, relType, null);shReflect.getCTWorksheet().addNewPicture().setId(pr.getId());}}/*** 给 Excel 添加水印** @param workbook XSSFWorkbook* @param waterMarkText 水印文字内容*/public static void insertWaterMarkTextToXlsx(XSSFWorkbook workbook, String waterMarkText) throws IOException {BufferedImage image = createWatermarkImage(waterMarkText);ByteArrayOutputStream imageOs = new ByteArrayOutputStream();ImageIO.write(image, "png", imageOs);int pictureIdx = workbook.addPicture(imageOs.toByteArray(), XSSFWorkbook.PICTURE_TYPE_PNG);XSSFPictureData pictureData = workbook.getAllPictures().get(pictureIdx);for (int i = 0; i < workbook.getNumberOfSheets(); i++) {//获取每个Sheet表XSSFSheet sheet = workbook.getSheetAt(i);PackagePartName ppn = pictureData.getPackagePart().getPartName();String relType = XSSFRelation.IMAGES.getRelation();PackageRelationship pr = sheet.getPackagePart().addRelationship(ppn, TargetMode.INTERNAL, relType, null);sheet.getCTWorksheet().addNewPicture().setId(pr.getId());}}/*** 创建水印图片** @param waterMark 水印文字*/public static BufferedImage createWatermarkImage(String waterMark) {String[] textArray = waterMark.split("\n");Font font = new Font("microsoft-yahei", Font.PLAIN, 32);int width = 500;int height = 400;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(Color.lightGray.getRGB()));// 设定画笔颜色g.setFont(font);// 设置画笔字体// g.shear(0.1, -0.26);// 设定倾斜度// 设置字体平滑g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);//文字从中心开始输入,算出文字宽度,左移动一半的宽度,即居中FontMetrics fontMetrics = g.getFontMetrics(font);// 水印位置int x = width / 2;int y = height / 2;// 设置水印旋转g.rotate(Math.toRadians(-40), x, y);for (String s : textArray) {// 文字宽度int textWidth = fontMetrics.stringWidth(s);g.drawString(s, x - (textWidth / 2), y);// 画出字符串y = y + font.getSize();}g.dispose();// 释放画笔return image;}/*** 设置打印的参数** @param wb XSSFWorkbook*/public static void setPrintParams(XSSFWorkbook wb) {XSSFSheet sheet = wb.getSheetAt(0);XSSFPrintSetup printSetup = sheet.getPrintSetup();// 打印方向,true:横向,false:纵向(默认printSetup.setLandscape(true);//设置A4纸printSetup.setPaperSize(XSSFPrintSetup.A4_PAPERSIZE);// 将整个工作表打印在一页(缩放),如果行数很多的话,可能会出问题// sheet.setAutobreaks(true);//将所有的列调整为一页,行数多的话,自动分页printSetup.setScale((short) 70);//缩放的百分比,自行调整sheet.setAutobreaks(false);}
}
三、如何使用
代码如下(示例1):
XSSFWorkbook workbook = new XSSFWorkbook();//...你的逻辑...WaterMarkUtil.insertWaterMarkTextToXlsx(workbook); //调用这段代码后水印就添加成功了
代码如下(示例2):
SXSSFWorkbook workbook = new SXSSFWorkbook();//...你的逻辑...WaterMarkUtil.insertWaterMarkTextToXlsx(workbook); //调用这段代码后水印就添加成功了
四、总结
- 注意这个工具类不支持 HSSFWorkbook 导出的方式
- SXSSFWorkbook 模式导出为什么要用反射?
因为 SXSSFWorkbook 通过
SXSSFSheet sheet = workbook.getSheetAt(i);
获取SXSSFSheet
,SXSSFSheet
中没有XSSFSheet
的方法,
而且SXSSFSheet
中的XSSFSheet
是被final
修饰的final XSSFSheet _sh;
所以可以用个取到反射从SXSSFSheet
中取到XSSFSheet
,这样就解决了没有XSSFSheet
中类中方法的问题了五、参考
POI导出 Excel 加水印支持 SXSSFWorkbook 和 XSSFWorkbook 模式相关推荐
- POI导出EXCEL带水印 以及单元格格式设置
客户提个需求,需要将报表导出 excel带水印 和 pdf带水印 2个版本. 做的时候连excel本身怎么带水印都不知道,更不用说用java了.后来在网上搜到了excel添加水印的2个方法. 1.艺术 ...
- Java使用POI为Excel打水印,调整列宽并设置Excel只读
武林游戏 2017-05-02 11:15 本文介绍在Java语言环境下,使用POI为Excel打水印的解决方案,具体的代码编写以及相关的注意事项. 需求描述: 要求通过系统下载的Excel都带上公司 ...
- JAVA POI导出EXCEL设置自定义样式(线框加粗,合并指定行,合计求和,冻结行)
前面部分是当时查询的记录: 实现Excel文件单元格合并.冻结和文件导出 Workbook wb = new HSSFWorkbook();Sheet sheet = wb.createSheet(& ...
- poi导出excel,给excel加背景色。兼容office和wps
最近一段时间在研究poi导出excel的时候给excel加一些样式,像居中,设置字体之类的在网上搜的方法都是可以表现出来的,但是在设置背景色的时候遇到了一些问题,使用 cellStyle.setFil ...
- Java利用注解实现配置动态公式并结合POI导出Excel
利用注解实现动态配置公式并结合POI导出Excel 实现思想 创建导出对象 创建使用注解类 创建封装导出对象属性类 创建测试类 创建ExcelUtil类 实现效果 实现思想 实施顾问提出导出Excel ...
- excel加水印,由于excel没有加水印功能,实际上操作是将图片丢进去
目录 1.依赖 2.controller层代码 3.工具类 1.依赖 <!--excel poi--><dependency><groupId>org.apache ...
- POI导出Excel遇到数据量大该如何解决
最近在使用Java POI导出Excel,使用的是XSSFWorkbook ,遇到数据量超过10w的话程序会爆内存溢出的错误,将XSSFWorkbook 换成SXSSFWorkbook 即可 SXSS ...
- POI导出Excel (满满的干货啊)
已经实现的POI导出Excel 步骤一:导入依赖 <dependency><groupId>org.apache.poi</groupId><artifact ...
- JAVA导出Excel通用工具类——第一篇:详细介绍POI 导出excel的多种复杂情况,包括动态设置筛选、动态合并横向(纵向)单元格等多种复杂情况——保姆级别,真的不能再详细了,代码拿来即用)
JAVA导出Excel通用工具--第一篇:详细介绍POI 导出excel的多种复杂情况,包括动态设置筛选.动态合并横向(纵向)单元格等多种复杂情况--保姆级别,真的不能再详细了,封装通用工具类,代码拿 ...
- Java POI 导出EXCEL经典实现 Java导出Excel弹出下载框
原文转载:http://blog.csdn.net/evangel_z/article/details/7332535 目录(?)[+] 在web开发中,有一个经典的功能,就是数据的导入导出.特别是数 ...
最新文章
- java生成验证码登录,生成验证码
- 安装orb_slam 的坑解决方法
- Python基础教程:迭代器
- 微软亚洲研究院的“人立方”搜索
- PL/SQL Developer使用技巧总结
- ruby on rails ajax select
- libcap-ng库旨在使具有posix功能的编程比传统的libcap库容易得多
- python中or的用法_解析python中and与or用法
- 【已解决】Could not get lock /var/lib/dpkg/lock-frontend
- Oracle 新建用户、赋予权限
- JAVA中如何产生透明的VolatileImage
- 电子仿真软件MultiSIM
- udp 消息转发 服务器,UDP消息发送
- 图纸管理协同办公软件推荐
- 计算机专业考信息安全研究生,我是计算机科学与技术专业的学生,想考信息安全的研究生,我们本专业涉及的知识主要是计算机的组成原理,...
- kalibr源码解析之fov模型重投影误差计算
- 解读神经网络十大误解,再也不会弄错它的工作原理
- MYSQL数据库学习总结
- 全志h2参数_全志h3芯片性能及参数评测
- 记录一下获取的动态ip与路由器ip不符所以要纠错的日常