java POI为excel添加水印

网络上充斥着各种为excel添加水印的方法,但是多数效果不敢恭维,这里介绍两种添加excel水印的方法,最终实现的效果跟excel工具添加的水印无异,个人比较喜欢比较推荐。
这里说是两种,其实原理是一种,只不过因为poi的版本高低不同,导致了我们的操作发生了变化,大家可以根据自己的poi版本对应选择不同的实现方法。
这两种方法应用的时候是比较久之前了,最近想起来整理一下,可能文章中会有错误,还请口下饶人,有问题我会及时讨论更正。

关于转载说明:

第一种POI比较老的版本中,水印图片绑定参考的资料只记得是一个外国网站,因为时间久远,记不得原始链接了,还请见谅。水印生成工具类参考的是哪个网站也记不清了,求原谅。

第二种是在改造开源项目的时候发现第一种没办法用的情况下借鉴的他人资料,参考的地址为:
https://www.iflym.com/index.php/code/201412280001.html
跟原文有无区别记不太清了,印象里是有改造过,但是终究是借鉴了这篇帖子无疑。

效果图:

水印不会影响到文本的编辑,是真水印,不是重复贴图做成的水印。
在这里插入图片描述

生成水印图片的类,两种方法都会用到该类

public class FontImage {

    @Data
    public static class Watermark {
        private Boolean enable;
        private String text;
        private String dateFormat;
        private String color;
    }

    public static BufferedImage createWatermarkImage(Watermark watermark) {
        if (watermark == null) {
            watermark = new FontImage.Watermark();
            watermark.setEnable(true);
//            watermark.setText("userName");
            watermark.setText("内部资料");
            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 (StringUtils.isEmpty(watermark.getText())) {
                watermark.setText("内部资料");
            }
            if (StringUtils.isEmpty(watermark.getColor())) {
                watermark.setColor("#C5CBCF");
            }
        }
        String[] textArray = watermark.getText().split("\n");
        Font font = new Font("microsoft-yahei", Font.PLAIN, 20);
        Integer width = 300;
        Integer height = 100;

        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.1, -0.26);// 设定倾斜度

//        设置字体平滑
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        int y = 50;
        for (int i = 0; i < textArray.length; i++) {
            g.drawString(textArray[i], 0, y);// 画出字符串
            y = y + font.getSize();
        }
        g.drawString(DateUtils.getNowDateFormatCustom(watermark.getDateFormat()), 0, y);// 画出字符串

        g.dispose();// 释放画笔
        return image;

    }
}

第一种,基于POI的老版本

pom文件中添加以下依赖

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.17</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.17</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml-schemas</artifactId>
            <version>3.14</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>ooxml-schemas</artifactId>
            <version>1.0</version>
        </dependency>

java核心代码

try {
            XSSFWorkbook workbook = new XSSFWorkbook();
            FileOutputStream out = new FileOutputStream("/Users/Tony/Downloads/out.xls");

                XSSFSheet sheet = workbook.createSheet("Sheet1");
            workbook.getSheet("Sheet1");

                //add picture data to this workbook.
//                FileInputStream is = new FileInputStream("/Users/Tony/Downloads/data_image.png");
//            byte[] bytes = IOUtils.toByteArray(is);



            BufferedImage image = FontImage.createBufferedImage("科技有限公司", new Font("microsoft-yahei", Font.PLAIN, 20), 300, 100, true);
            // 导出到字节流B
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            ImageIO.write(image, "png", os);

            int pictureIdx = workbook.addPicture(os.toByteArray(), Workbook.PICTURE_TYPE_PNG);
//            is.close();

                //add relation from sheet to the picture data
                String rID = sheet.addRelation(null, XSSFRelation.IMAGES, workbook.getAllPictures().get(pictureIdx)).getRelationship().getId();
                //set background picture to sheet
                sheet.getCTWorksheet().addNewPicture().setId(rID);

                workbook.write(out);

        } catch (Exception e) {
            e.printStackTrace();
        }

第二种,基于POI的高版本

pom文件中添加以下依赖

该方法中用不用的到ooxml-schemas依赖记不清了,可以删除尝试下

<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.0</version>
    </dependency>

java核心代码

BufferedImage image = FontImage.createBufferedImage("科技有限公司", new Font("microsoft-yahei", Font.PLAIN, 20), 300, 100, true);
            // 导出到字节流B
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            ImageIO.write(image, "png", os);

            XSSFWorkbook workbook = new XSSFWorkbook(is);
            int pictureIdx = workbook.addPicture(os.toByteArray(), Workbook.PICTURE_TYPE_PNG);
            POIXMLDocumentPart poixmlDocumentPart = workbook.getAllPictures().get(pictureIdx);
            for (int i = 0; i < workbook.getNumberOfSheets(); i++) {//获取每个Sheet表
                XSSFSheet sheet = workbook.getSheetAt(i);
                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());
            }

            workbook.write(response.getOutputStream());
  • 11
    点赞
  • 63
    收藏
    觉得还不错? 一键收藏
  • 61
    评论
在使用POI库操作Excel文件时,可以通过添加水印的方式来给Excel文件添加背景图案或文字标识。下面是一个简单的示例代码来演示如何使用POI添加水印。 首先,我们需要导入POI库的相关类: ``` import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFSheet; ``` 然后,我们需要加载Excel文件并创建一个工作簿对象: ``` String filePath = "path/to/excel/file.xlsx"; Workbook workbook = new XSSFWorkbook(filePath); ``` 接下来,创建一个新的工作表对象,并获取当前工作表的绘图对象: ``` Sheet sheet = workbook.createSheet(); Drawing drawing = sheet.createDrawingPatriarch(); ``` 创建一个文本对象,并设置文本内容以及位置: ``` ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 1, 2, 3, 4); TextShape text = drawing.createTextbox(anchor); text.setText("水印文字"); ``` 设置文本样式、字体、颜色等: ``` text.setLineStyle(LineStyle.NONE); text.setNoFill(true); text.setVerticalAlignment(VerticalAlignment.CENTER); text.setHorizontalAlignment(HorizontalAlignment.CENTER); text.setFontFamily("宋体"); text.setFontSize(20); text.setFillColor(IndexedColors.GREY_25_PERCENT.getIndex()); ``` 最后,保存修改并关闭Excel文件: ``` FileOutputStream fileOut = new FileOutputStream("path/to/output/file.xlsx"); workbook.write(fileOut); fileOut.close(); workbook.close(); ``` 通过以上代码,我们可以将"水印文字"添加Excel文件的水印。可以根据自己的需求调整水印的位置、样式和内容等。同时需要注意的是,以上代码适用于POI版本为4.1.2。 希望以上内容对您有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 61
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值