Excel添加水印【源码下载

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

步骤二:

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

案例源码:

  1. import java.awt.image.BufferedImage;
  2. import java.io.ByteArrayOutputStream;
  3. import java.io.File;
  4. import java.io.FileInputStream;
  5. import java.io.FileOutputStream;
  6. import java.io.InputStream;
  7. import java.io.OutputStream;
  8. import java.util.Date;
  9. import java.util.UUID;
  10.  
  11. import javax.imageio.ImageIO;
  12.  
  13. import org.apache.poi.ss.usermodel.ClientAnchor;
  14. import org.apache.poi.ss.usermodel.Drawing;
  15. import org.apache.poi.ss.usermodel.Picture;
  16. import org.apache.poi.ss.usermodel.Sheet;
  17. import org.apache.poi.ss.usermodel.Workbook;
  18. import org.apache.poi.xssf.usermodel.XSSFWorkbook;
  19.  
  20. public class ExcelWaterRemarkUtils {
  21. public static void main(String[] args) throws Exception {
  22. String waterRemarkPath = "E:\\NO5\\123.png";
  23. String tmpName = "E:\\NO5\\测试.xlsx";
  24. String tmpName2 = "E:\\NO5\\测试2.xlsx";
  25. Date a = new Date();
  26. XSSFWorkbook wb=new XSSFWorkbook(new FileInputStream(tmpName));
  27. //添加水印
  28. ExcelWaterRemarkUtils.betweenYRow(wb, waterRemarkPath);
  29.  
  30. ByteArrayOutputStream os = new ByteArrayOutputStream();
  31. wb.write(os);
  32. byte[] content = os.toByteArray();
  33. File file1 = new File(tmpName2);// Excel文件生成后存储的位置。
  34. OutputStream fos = new FileOutputStream(file1);
  35. fos.write(content);
  36. os.close();
  37. fos.close();
  38.  
  39. Date b = new Date();
  40. long interval = (b.getTime() - a.getTime())/1000;
  41. System.out.println("两个时间相差"+interval+"秒");//会打印出相差几秒
  42. System.out.println("jdldbjo");
  43. }
  44.  
  45. /**
  46. * 为Excel打上水印工具函数 请自行确保参数值,以保证水印图片之间不会覆盖。 在计算水印的位置的时候,并没有考虑到单元格合并的情况,请注意
  47. *
  48. * @param wb
  49. * Excel Workbook
  50. * @param sheet
  51. * 需要打水印的Excel
  52. * @param waterRemarkPath
  53. * 水印地址,classPath,目前只支持png格式的图片,
  54. * 因为非png格式的图片打到Excel上后可能会有图片变红的问题,且不容易做出透明效果。
  55. * 同时请注意传入的地址格式,应该为类似:"\\excelTemplate\\test.png"
  56. * @param startXCol
  57. * 水印起始列
  58. * @param startYRow
  59. * 水印起始行
  60. * @param betweenXCol
  61. * 水印横向之间间隔多少列
  62. * @param betweenYRow
  63. * 水印纵向之间间隔多少行
  64. * @param XCount
  65. * 横向共有水印多少个
  66. * @param YCount
  67. * 纵向共有水印多少个
  68. * @param waterRemarkWidth
  69. * 水印图片宽度为多少列
  70. * @param waterRemarkHeight
  71. * 水印图片高度为多少行
  72. * @throws IOException
  73. */
  74. public static void betweenYRow(Workbook wb, String waterRemarkPath) throws Exception {
  75. int startXCol=0; //水印起始列
  76. int startYRow=0; // 水印起始行
  77. int betweenXCol=1; //水印横向之间间隔多少列
  78. int betweenYRow=3; //水印纵向之间间隔多少行
  79. int XCount=0; //横向共有水印多少个
  80. int YCount=0; //纵向共有水印多少个
  81. int waterRemarkWidth=0; //水印图片宽度为多少列
  82. int waterRemarkHeight=0; // 水印图片高度为多少行
  83.  
  84. // 校验传入的水印图片格式
  85. if (!waterRemarkPath.endsWith("png") && !waterRemarkPath.endsWith("PNG")) {
  86. throw new RuntimeException("向Excel上面打印水印,目前支持png格式的图片。");
  87. }
  88.  
  89. // 加载图片
  90. ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();
  91. InputStream imageIn=new FileInputStream(waterRemarkPath);
  92. if (null == imageIn || imageIn.available() < 1) {
  93. throw new RuntimeException("向Excel上面打印水印,读取水印图片失败(1)。");
  94. }
  95. BufferedImage bufferImg = ImageIO.read(imageIn);
  96. if (null == bufferImg) {
  97. throw new RuntimeException("向Excel上面打印水印,读取水印图片失败(2)。");
  98. }
  99. ImageIO.write(bufferImg, "png", byteArrayOut);
  100.  
  101. for(int i=0; i<wb.getNumberOfSheets(); i++){ // wb.getNumberOfSheets()
  102. System.err.println("num:"+ wb.getNumberOfSheets());
  103. System.err.println("i:"+ i);
  104. Sheet sheet = wb.getSheetAt(i);
  105. sheet.protectSheet(UUID.randomUUID().toString());
  106. try {
  107. XCount = (sheet.getRow(0).getLastCellNum()); //横向共有水印多少个
  108. if(XCount == 0){
  109. XCount = 2;
  110. }
  111. if(XCount >= 5){
  112. XCount = 5;
  113. }
  114.  
  115. } catch (Exception e) {
  116. XCount = 10;
  117. }
  118. try {
  119. YCount=sheet.getLastRowNum()/(betweenYRow); //纵向共有水印多少个
  120. if(YCount < 6){
  121. YCount = 6;
  122. }
  123.  
  124. } catch (Exception e) {
  125. YCount = 50;
  126. }
  127.  
  128. System.err.println("XCount:"+ XCount);
  129. System.err.println("YCount:"+ YCount);
  130. // 开始打水印
  131. Drawing drawing = sheet.createDrawingPatriarch();
  132. // 按照共需打印多少行水印进行循环
  133. for (int yCount = 0; yCount < YCount; yCount++) {
  134. // 按照每行需要打印多少个水印进行循环
  135. for (int xCount = 0; xCount < XCount; xCount++) {
  136. // 创建水印图片位置
  137. int xIndexInteger = startXCol + (xCount * waterRemarkWidth) + (xCount * betweenXCol);
  138. int yIndexInteger = startYRow + (yCount * waterRemarkHeight) + (yCount * betweenYRow);
  139. /*
  140. * 参数定义: 第一个参数是(x轴的开始节点); 第二个参数是(是y轴的开始节点); 第三个参数是(是x轴的结束节点);
  141. * 第四个参数是(是y轴的结束节点); 第五个参数是(是从Excel的第几列开始插入图片,从0开始计数);
  142. * 第六个参数是(是从excel的第几行开始插入图片,从0开始计数); 第七个参数是(图片宽度,共多少列);
  143. * 第8个参数是(图片高度,共多少行);
  144. */
  145. //System.err.println("xIndexInteger:"+ xIndexInteger+", yIndexInteger:"+ yIndexInteger);
  146. ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, xIndexInteger,
  147. yIndexInteger, xIndexInteger+waterRemarkWidth, yIndexInteger+waterRemarkHeight);
  148.  
  149. Picture pic = drawing.createPicture(anchor,
  150. wb.addPicture(byteArrayOut.toByteArray(), Workbook.PICTURE_TYPE_PNG));
  151. pic.resize();
  152.  
  153. }
  154. }
  155. }
  156. }
  157. }

生成水印图片的源码:

  1. /**
  2. *
  3. * @param content 水印文字
  4. * @param path 图片生成路径
  5. * @throws IOException
  6. *
  7. */
  8. public static void createWaterMark(String content,String path) throws IOException{
  9. Integer width = 120;
  10. Integer height = 90;
  11. BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);// 获取bufferedImage对象
  12. String fontType = "宋体";
  13. Integer fontStyle = 0;
  14. Integer fontSize = 16;
  15. Font font = new Font(fontType, fontStyle, fontSize);
  16. Graphics2D g2d = image.createGraphics(); // 获取Graphics2d对象
  17. image = g2d.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT);
  18. g2d.dispose();
  19. g2d = image.createGraphics();
  20. g2d.setColor(new Color(0, 0, 0, 50)); //设置字体颜色和透明度
  21. g2d.setStroke(new BasicStroke(1)); // 设置字体
  22. g2d.setFont(font); // 设置字体类型 加粗 大小
  23.  
  24. g2d.rotate(Math.toRadians(-10),(double) image.getWidth() / 2, (double) image.getHeight() / 2);//设置倾斜度
  25.  
  26. FontRenderContext context = g2d.getFontRenderContext();
  27. Rectangle2D bounds = font.getStringBounds(content, context);
  28. double x = (width - bounds.getWidth()) / 2;
  29. double y = (height - bounds.getHeight()) / 2;
  30. double ascent = -bounds.getY();
  31. double baseY = y + ascent;
  32. // 写入水印文字原定高度过小,所以累计写水印,增加高度
  33. g2d.drawString(content, (int)x, (int)baseY);
  34. // 设置透明度
  35. g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
  36. // 释放对象
  37. g2d.dispose();
  38. ImageIO.write(image, "png", new File(path));
  39. }

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. Dynamic Resource – 动态资源

      Dynamic Resource – 动态资源 与Static Resource不同的是,Dynamic Resource可以在程序运行时重新评估/计算资源来生成对应的对象/值,它支持向前引用,只 ...

  2. 大白第一章第四节dp例题

    入口 UVALive - 3882 #include<cstdio> using namespace std; ; int n,m,k,f[N]; int main(){ //f[i]表示 ...

  3. EasyPlayer RTSP 安卓Android播放器显示模式设置方法

    一般对于一个播放器,应该支持如下几种显示模式: 等比例,最大化区域显示,不裁剪 等比例,最大区域显示,裁剪 拉伸显示,铺满全屏 要实现这几种显示模式,其实只要对播放控件的布局进行些许调整即可.那Eas ...

  4. AWS:1.相关概念、创建云主机的过程

    概念 EC2是弹性的云计算 云主机 也即虚拟机,由分配的CPU.内存.网络和磁盘等资源组成 好处:维护成本低(主机替换).环境升级成本低 AMI:映像 创建云主机的蓝图,指定初始状态1 预装什么操作系 ...

  5. 【题解】P3129高低卡(白金)High Card Low Card

    [题解][P3129 USACO15DEC]高低卡(白金)High Card Low Card (Platinum) 考虑贪心. 枚举在第几局改变规则,在改变规则之前,尽量出比它大的最小的牌,在改变规 ...

  6. Coin和Token有什么区别

    在币圈,经常可以听到“coin”和“token”这些词汇,他们究竟分别代表什么,有什么区别呢?下面本文就和大家一起来扒一扒. 什么是coin? coin (包括山寨coin)是一种数字货币,它通过加密 ...

  7. 将QQ登录接口整合到你的网站和如何修改配置

    http://www.phpfensi.com/php/20140727/3998.html 摘要:QQ登录的官方SDK进行了一些修改,使其更加容易的整合到自己的网站上去... 对QQ登录的官方SDK ...

  8. php 身份证号码获取星座和生肖

    发布:thatboy   来源:Net     [大 中 小] 本文介绍下,php用身份证号码获取星座和生肖的方法,一个简单的php实例,从身份证号码中取得星座与生肖信息,有兴趣的朋友参考研究下吧.本 ...

  9. java集合讲解干货集

    文章都来自网络,收集后便于查阅. 1.Java 集合系列01之 总体框架 2.Java 集合系列02之 Collection架构 3.Java 集合系列03之 ArrayList详细介绍(源码解析)和 ...

  10. Builder 模式初探

    Builder 模式是一步一步创建一个复杂对象的创建型模式,它允许用户在不知道内部构建细节的情况下,可以更精细的控制对象的构造流程.该模式是为了将构建复杂对象的过程和它的部件解耦,使得构建过程和部件的 ...