导出生成有水印的excel文件

上代码跑一下即可
pom

   <poi.ooxml.version>4.1.2</poi.ooxml.version>
        <ooxml.schemas.version>1.4</ooxml.schemas.version>
   <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>${poi.ooxml.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>ooxml-schemas</artifactId>
            <version>${ooxml.schemas.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>${poi.ooxml.version}</version>
        </dependency>
package com.liuhm.demo;

import cn.hutool.core.date.DateUtil;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ooxml.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.*;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Date;

/**
 * excel操作类
 *
 * @author liuhaomin
 * @date 2020-8-8 11:36:09
 */
@Slf4j
public class ExcelUtils {
     
	/**
	 * 字体图片
	 * @author liuhaomin
	 * @date 2020-8-8 11:36:09
	 */
	static class FontImage {
     
		final static String[] TEXT = new String[]{
     "xxx系统"};
		@Data
		@AllArgsConstructor
		@NoArgsConstructor
		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 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, 12);
			Integer width = 300;
			Integer height = 70 * watermark.getText().length;

			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_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
			//设置字体平滑
			g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

			int y =60;
			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;
		}
	}

	/**
	 * 添加水印
	 * @param wb
	 * @param sheet
	 * @param waterMark
	 */
	public static void addWaterMark(XSSFWorkbook wb, XSSFSheet sheet, String waterMark){
     
		//是否添加水印
		if(StringUtils.isNotBlank(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) {
     
				log.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());
		}
	}

	/**
	 * 添加水印
	 * @param wb
	 * @param sheet
	 * @param waterMarks
	 */
	public static void addWaterMark(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) {
     
				log.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());

		}
	}

	public static void main(String[] args) {
     
		// 指定创建的excel文件名称
		try {
     
			BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream("/data123.xlsx"));
			// 定义一个工作薄(所有要写入excel的数据,都将保存在workbook中)
			XSSFWorkbook workbook = new XSSFWorkbook();

			// 创建一个sheet
			XSSFSheet sheet = workbook.createSheet("my-sheet-1");
			XSSFSheet sheet2 = workbook.createSheet("my-sheet-2");

			// 开始写入数据流程,2大步:1、定位到单元格,2、写入数据;定位单元格,需要通过行、列配合指定。
			// step1: 先选择第几行(0表示第一行),下面表示在第6行
			XSSFRow row = sheet.createRow(5);
			// step2:选择第几列(0表示第一列),注意,这里的第几列,是在上面指定的row基础上,也就是第6行,第3列
			XSSFCell cell = row.createCell(2);
			// step3:设置单元格的数据(写入数据)
			cell.setCellValue("hello world");
			XSSFWorkbook xssfWorkbook = workbook;
			String[] ss=new String[]{
     "xxxx系统","超级管理员", DateUtil.formatDateTime(new Date())};
			for(int i=0;i<workbook.getNumberOfSheets();i++){
     
				ExcelUtils.addWaterMark(xssfWorkbook, xssfWorkbook.getSheetAt(i),ss);
			}
			// 执行写入操作
			workbook.write(outputStream);
			workbook.close();
			outputStream.flush();
			outputStream.close();
		} catch (Exception e) {
     
			e.printStackTrace();
		}
	}
}

效果图如下
导出生成有水印的excel文件_第1张图片

你可能感兴趣的:(java0基础)