Excel添加水印【源码下载

步骤一:根据生成图片的类创建水印图片

步骤二:

  • 代码在Excel中根据第一行获取sheet的列数【sheet.getRow(0).getLastCellNum() 】,根据【sheet.getLastRowNum()】获取整个sheet的行数。
  • 使用【sheet.protectSheet(UUID.randomUUID().toString());】为每个sheet添加密码,防止sheet被修改
  • 在Excel中添加水印
                    /*
* 参数定义: 第一个参数是(x轴的开始节点); 第二个参数是(是y轴的开始节点); 第三个参数是(是x轴的结束节点);
* 第四个参数是(是y轴的结束节点); 第五个参数是(是从Excel的第几列开始插入图片,从0开始计数);
* 第六个参数是(是从excel的第几行开始插入图片,从0开始计数); 第七个参数是(图片宽度,共多少列);
* 第8个参数是(图片高度,共多少行);
*/
ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, xIndexInteger,
yIndexInteger, xIndexInteger+waterRemarkWidth, yIndexInteger+waterRemarkHeight); Picture pic = drawing.createPicture(anchor,
wb.addPicture(byteArrayOut.toByteArray(), Workbook.PICTURE_TYPE_PNG));
pic.resize();

案例源码:

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;
import java.util.UUID; import javax.imageio.ImageIO; import org.apache.poi.ss.usermodel.ClientAnchor;
import org.apache.poi.ss.usermodel.Drawing;
import org.apache.poi.ss.usermodel.Picture;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook; public class ExcelWaterRemarkUtils {
public static void main(String[] args) throws Exception {
String waterRemarkPath = "E:\\NO5\\123.png";
String tmpName = "E:\\NO5\\测试.xlsx";
String tmpName2 = "E:\\NO5\\测试2.xlsx";
Date a = new Date();
XSSFWorkbook wb=new XSSFWorkbook(new FileInputStream(tmpName));
//添加水印
ExcelWaterRemarkUtils.betweenYRow(wb, waterRemarkPath); ByteArrayOutputStream os = new ByteArrayOutputStream();
wb.write(os);
byte[] content = os.toByteArray();
File file1 = new File(tmpName2);// Excel文件生成后存储的位置。
OutputStream fos = new FileOutputStream(file1);
fos.write(content);
os.close();
fos.close(); Date b = new Date();
long interval = (b.getTime() - a.getTime())/1000;
System.out.println("两个时间相差"+interval+"秒");//会打印出相差几秒
System.out.println("jdldbjo");
} /**
* 为Excel打上水印工具函数 请自行确保参数值,以保证水印图片之间不会覆盖。 在计算水印的位置的时候,并没有考虑到单元格合并的情况,请注意
*
* @param wb
* Excel Workbook
* @param sheet
* 需要打水印的Excel
* @param waterRemarkPath
* 水印地址,classPath,目前只支持png格式的图片,
* 因为非png格式的图片打到Excel上后可能会有图片变红的问题,且不容易做出透明效果。
* 同时请注意传入的地址格式,应该为类似:"\\excelTemplate\\test.png"
* @param startXCol
* 水印起始列
* @param startYRow
* 水印起始行
* @param betweenXCol
* 水印横向之间间隔多少列
* @param betweenYRow
* 水印纵向之间间隔多少行
* @param XCount
* 横向共有水印多少个
* @param YCount
* 纵向共有水印多少个
* @param waterRemarkWidth
* 水印图片宽度为多少列
* @param waterRemarkHeight
* 水印图片高度为多少行
* @throws IOException
*/
public static void betweenYRow(Workbook wb, String waterRemarkPath) throws Exception {
int startXCol=0; //水印起始列
int startYRow=0; // 水印起始行
int betweenXCol=1; //水印横向之间间隔多少列
int betweenYRow=3; //水印纵向之间间隔多少行
int XCount=0; //横向共有水印多少个
int YCount=0; //纵向共有水印多少个
int waterRemarkWidth=0; //水印图片宽度为多少列
int waterRemarkHeight=0; // 水印图片高度为多少行 // 校验传入的水印图片格式
if (!waterRemarkPath.endsWith("png") && !waterRemarkPath.endsWith("PNG")) {
throw new RuntimeException("向Excel上面打印水印,目前支持png格式的图片。");
} // 加载图片
ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();
InputStream imageIn=new FileInputStream(waterRemarkPath);
if (null == imageIn || imageIn.available() < 1) {
throw new RuntimeException("向Excel上面打印水印,读取水印图片失败(1)。");
}
BufferedImage bufferImg = ImageIO.read(imageIn);
if (null == bufferImg) {
throw new RuntimeException("向Excel上面打印水印,读取水印图片失败(2)。");
}
ImageIO.write(bufferImg, "png", byteArrayOut); for(int i=0; i<wb.getNumberOfSheets(); i++){ // wb.getNumberOfSheets()
System.err.println("num:"+ wb.getNumberOfSheets());
System.err.println("i:"+ i);
Sheet sheet = wb.getSheetAt(i);
sheet.protectSheet(UUID.randomUUID().toString());
try {
XCount = (sheet.getRow(0).getLastCellNum()); //横向共有水印多少个
if(XCount == 0){
XCount = 2;
}
if(XCount >= 5){
XCount = 5;
} } catch (Exception e) {
XCount = 10;
}
try {
YCount=sheet.getLastRowNum()/(betweenYRow); //纵向共有水印多少个
if(YCount < 6){
YCount = 6;
} } catch (Exception e) {
YCount = 50;
} System.err.println("XCount:"+ XCount);
System.err.println("YCount:"+ YCount);
// 开始打水印
Drawing drawing = sheet.createDrawingPatriarch();
// 按照共需打印多少行水印进行循环
for (int yCount = 0; yCount < YCount; yCount++) {
// 按照每行需要打印多少个水印进行循环
for (int xCount = 0; xCount < XCount; xCount++) {
// 创建水印图片位置
int xIndexInteger = startXCol + (xCount * waterRemarkWidth) + (xCount * betweenXCol);
int yIndexInteger = startYRow + (yCount * waterRemarkHeight) + (yCount * betweenYRow);
/*
* 参数定义: 第一个参数是(x轴的开始节点); 第二个参数是(是y轴的开始节点); 第三个参数是(是x轴的结束节点);
* 第四个参数是(是y轴的结束节点); 第五个参数是(是从Excel的第几列开始插入图片,从0开始计数);
* 第六个参数是(是从excel的第几行开始插入图片,从0开始计数); 第七个参数是(图片宽度,共多少列);
* 第8个参数是(图片高度,共多少行);
*/
//System.err.println("xIndexInteger:"+ xIndexInteger+", yIndexInteger:"+ yIndexInteger);
ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, xIndexInteger,
yIndexInteger, xIndexInteger+waterRemarkWidth, yIndexInteger+waterRemarkHeight); Picture pic = drawing.createPicture(anchor,
wb.addPicture(byteArrayOut.toByteArray(), Workbook.PICTURE_TYPE_PNG));
pic.resize(); }
}
}
}
}

生成水印图片的源码:

/**
*
* @param content 水印文字
* @param path 图片生成路径
* @throws IOException
*
*/
public static void createWaterMark(String content,String path) throws IOException{
Integer width = 120;
Integer height = 90;
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);// 获取bufferedImage对象
String fontType = "宋体";
Integer fontStyle = 0;
Integer fontSize = 16;
Font font = new Font(fontType, fontStyle, fontSize);
Graphics2D g2d = image.createGraphics(); // 获取Graphics2d对象
image = g2d.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT);
g2d.dispose();
g2d = image.createGraphics();
g2d.setColor(new Color(0, 0, 0, 50)); //设置字体颜色和透明度
g2d.setStroke(new BasicStroke(1)); // 设置字体
g2d.setFont(font); // 设置字体类型 加粗 大小 g2d.rotate(Math.toRadians(-10),(double) image.getWidth() / 2, (double) image.getHeight() / 2);//设置倾斜度 FontRenderContext context = g2d.getFontRenderContext();
Rectangle2D bounds = font.getStringBounds(content, context);
double x = (width - bounds.getWidth()) / 2;
double y = (height - bounds.getHeight()) / 2;
double ascent = -bounds.getY();
double baseY = y + ascent;
// 写入水印文字原定高度过小,所以累计写水印,增加高度
g2d.drawString(content, (int)x, (int)baseY);
// 设置透明度
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
// 释放对象
g2d.dispose();
ImageIO.write(image, "png", new File(path));
}

Excel添加水印的更多相关文章

  1. C#中如何给Excel添加水印

    我们知道Microsoft Excel并没有内置的功能直接给Excel表添加水印,但是其实我们可以用其他变通的方式来解决此问题,如通过添加页眉图片或艺术字的方法来模仿水印的外观.所以在这篇文章中,我将 ...

  2. Java使用POI为Excel打水印,调整列宽并设置Excel只读(用户不可编辑)

    本文介绍在Java语言环境下,使用POI为Excel打水印的解决方案,具体的代码编写以及相关的注意事项. 需求描述: 要求通过系统下载的Excel都带上公司的水印,列宽调整为合适的宽度,并且设置为不可 ...

  3. springboot为导出的pdf和excel加水印

    相信很多小伙伴们在做导出pdf或者excel文件时会被要求在文件上加上水印,本篇博客就来讲讲如何为pdf和excel加水印. 导出pdf加水印 其实在导出pdf时加上水印并不难,因为itext提供了添 ...

  4. Java 在Excel中添加水印(单一水印、平铺水印)

    在Excel中没有直接添加水印的功能,但依旧可以通过一定方式来实现类似水印效果.本文通过Java程序代码介绍具体实现方法.可添加单一水印效果,即水印是以单个文本字样来呈现:也可添加多个平铺水印效果,即 ...

  5. C# 操作Excel加水印

    首先下载免费版的Excel组件- Spire.XLS,安装完成后在bin目录里面有需要用到的dll文件,引用到自己项目里面. 我这里全引进来了,一共就四个: 界面 效果 全部代码 private st ...

  6. Python处理Excel和PDF文档

    一.使用Python操作Excel Python来操作Excel文档以及如何利用Python语言的函数和表达式操纵Excel文档中的数据. 虽然微软公司本身提供了一些函数,我们可以使用这些函数操作Ex ...

  7. 使用Spire.Office for .NET(Word、Excel、PPT、PDF等)的初步感受

    前言 本文大部分内容来自http://www.codeproject.com/Articles/710747/First-thoughts-on-Spire-Doc-for-NET. 针对我个人来说, ...

  8. C#&.Net干货分享- 构建Spire-Office相关Helper操作Word、Excel、PDF等

    先下载好如下的组件: 直接使用完整源码分享: namespace Frame.Office{    /// <summary>    /// Spire_WordHelper    /// ...

  9. java解决poi导出excel文字水印,导出excel不可操作问题

    首先需求是用户提出导出excel数据需使用水印备注其用途: 其实就是在导出excel的同时带有自定义文字水印的导出. 那么我们首先想到的肯定是以一个什么样的思路去解决该问题,首先查找poi导出exce ...

随机推荐

  1. VC++ 非托管代码 & 托管代码

    #pragma managed #pragma unmanaged 看了好多好多非托管代码和托管代码之间相互调用,感觉都没有说在重点上,到底怎么用才是关键,理论的东西我们到微软官网上就可以找到,毕竟这 ...

  2. visual C++ & Makefile

    Makefile说明: visual c++ 不通过IDE有3中方式对工程进行编译链接. 1.MSBuild 编译链接(IDE就是使用MSBuild,需要工程的.vcxproj和.filters文件) ...

  3. IT痴汉的工作现状10-Sprint Planning

    这是我们的第四个Sprint了.因为上一个迭代周期的失利,Leader群发邮件这样描写叙述道:"对任务的乐观预计,导致Sprint 3没有如期完毕. 我们须要在这次Sprint计划中细致评估 ...

  4. PHP 获取网络接口文件流

    获取网络接口里面的文件流 php开发调用各种接口在所难免,有时须要传递非常多參数. 在传递參数过程中 '&' 有时会被 解析成 '&'导致请求失败 经过查找资料和比較,发现php提供了 ...

  5. Linux 设置mysql开机启动

    linux开启启动的程序一般放在/etc/rc.d/init.d/里面,/etc/init.d/是其软连接 mysql设为linux服务 cp /usr/local/mysql/support-fil ...

  6. 微信小程序设计指南

    微信小程序设计指南 · 小程序 https://developers.weixin.qq.com/miniprogram/design/index.html

  7. Django框架ORM单表添加表记录_模型层

    此方法依赖的表时之前创建的过的一张表 参考链接:https://www.cnblogs.com/apollo1616/p/9840354.html 方法1: # 语法 [变量] = [表名].obje ...

  8. Servlet详解(转)

    我们通过浏览器访问一个网页的过程,实际上是浏览器(例如IE)通过HTTP协议(参见附录B)和Web服务器(也叫做HTTP服务器)进行交互的过程. 也就是说,用户要访问网络资源,首先需要在网络上架设We ...

  9. python连接redis并插入url

    #!/usr/bin/env python # -*- coding:utf8 -*- import redis ''' 这种连接是连接一次就断了,耗资源.端口默认6379,就不用写 r = redi ...

  10. A. Playing with Paper

    这是Codeforces Round #296 (Div. 2)的A题,题意就是: 小明有一张长为a,宽为b的纸,每当要折纸鹤时,就从纸上剪下一个正方形,然后,剩下的纸还可以剪出正方形,要是剩下的纸刚 ...