Java操作excel自动生成水印背景

操作基于spire的程序包,经代码及测试能够将导出的数据进行增加背景图片无问题,以下为代码:

代码看前先给个提醒吧,为啥要这么做呢是因为首先从操作上来说可以往excel中直接写入图片覆盖到数据层上面,但是这样并不严谨,肯定对用户操作有影响而且用户可以将水印图片删除掉,但是生成背景图片插入进去就不一样了,肯定不影响用户操作的前提下有了背景图,这时候除非去手动更换背景图不然不影响用户任何使用操作,看到过一堆写的乱七八糟的加水印的,其实就是往数据层上加了个图片,操作极为恶心根本没达到需求,还降低用户体验!

注:操作必须先生成水印图片并将水印图片添加至excel中,然后再将数据往excel中写入,否则在加入水印的时候会删除原excel文件并重新生成新的文件(原因是:因为懒没有去细看为啥会这样)。使用的包是 spire.xls.free-2.2.0.jar 做的测试POI包自己找一个吧。至于spire包网上搜的很多都收费,索性找到了弄个免费的链接吧,下载后自行解压使用。https://download.csdn.net/download/baidu_35051056/20401576

import com.spire.xls.ExcelVersion;
import com.spire.xls.Worksheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.Color;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.*;
import java.util.List;

/**
 * 创建excel 并保存背景图片(水印)
 */
public class CreateExcelImg {
    private static final String XLS = "xls";
    private static final String XLSX = "xlsx";

    /**
     * 创建水印图片
     *
     * @param content
     * @return
     * @throws IOException
     */
    public static void createWaterMark(String content, String filePath) throws IOException {
        Integer width = 300;
        Integer height = 200;
        // 获取bufferedImage对象
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        String fontType = "宋体";
        Integer fontStyle = java.awt.Font.PLAIN;
        Integer fontSize = 50;
        java.awt.Font font = new java.awt.Font(fontType, fontStyle, fontSize);
        // 获取Graphics2d对象
        Graphics2D g2d = image.createGraphics();
        image = g2d.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT);
        g2d.dispose();
        g2d = image.createGraphics();
        g2d.setColor(new Color(0, 0, 0, 80)); //设置字体颜色和透明度
        // 设置字体
        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(filePath));
    }

    /**
     * 为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 putWaterRemarkToExcel(Workbook wb, Sheet sheet, String waterRemarkPath, int startXCol,
                                             int startYRow, int betweenXCol, int betweenYRow, int XCount, int YCount, int waterRemarkWidth,
                                             int waterRemarkHeight) throws IOException {

        // 校验传入的水印图片格式
        if (!waterRemarkPath.endsWith("png") && !waterRemarkPath.endsWith("PNG")) {
            throw new RuntimeException("向Excel上面打印水印,目前支持png格式的图片。");
        }

        // 加载图片
        ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();
//        InputStream imageIn = new FileInputStream(waterRemarkPath);
        InputStream imageIn = Thread.currentThread().getContextClassLoader().getResourceAsStream(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);

        // 开始打水印
        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个参数是(图片高度,共多少行);
                 */
                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();
            }
        }
    }


    /**
     * 写入Excel
     *
     * @param dataList      写入Excel 的数据
     * @param cloumn        总列数
     * @param finalXlsxPath 写入路径
     */
    private static void writeExcel(List<Map> dataList, int cloumn, String finalXlsxPath) {
        OutputStream out = null;
        try {
            File finalXlsxFile = new File(finalXlsxPath);
            Workbook workBook = getWorkbok(finalXlsxFile);
            // sheet 工作页
            Sheet sheet = workBook.getSheetAt(0);
            //获取Excel最后一行
            int rowNumber = sheet.getLastRowNum();
            //empty
            for (int i = 1; i <= rowNumber; i++) {
                Row row = sheet.getRow(i);
                sheet.removeRow(row);
            }
            for (int j = 0; j < dataList.size(); j++) {
                // 创建一行:从第二行开始,跳过属性列
                Row row = sheet.createRow(j);
                // 得到要插入的每一条记录
                Map dataMap = dataList.get(j);
                int k = 0;
                //轮询map中的所有key值并赋值
                for (Iterator iterator = dataMap.keySet().iterator(); iterator.hasNext(); ) {
                    //获取Set集合中每一个键值
                    String key = (String) iterator.next();
                    //根据键值取map中的键对应的值;
                    Object value = dataMap.get(key);
                    Cell cell = row.createCell(k);
                    cell.setCellValue(value.toString());
                    k++;
                }
            }
            // 创建文件输出流,准备输出电子表格:这个必须有,否则你在sheet上做的任何操作都不会有效
            out = new FileOutputStream(finalXlsxPath);
            workBook.write(out);
        } catch (Exception e) {
            System.out.println("error error" + e);
        } finally {
            try {
                if (out != null) {
                    out.flush();
                    out.close();
                    System.out.println("数据导出成功");
                }
            } catch (IOException e) {
                System.out.println("error error error" + e);
            }
        }
    }

    //判断Excel格式(在此有点鸡肋,当做功能拓展~_~)
    public static Workbook getWorkbok(File file) throws IOException {
        Workbook wb = null;
        FileInputStream in = new FileInputStream(file);
        if (file.getName().endsWith(XLS)) {     //Excel&nbsp;2003
            wb = new HSSFWorkbook(in);
        } else if (file.getName().endsWith(XLSX)) {    // Excel 2007/2010
            wb = new XSSFWorkbook(in);
        }
        return wb;
    }

    /**
     * 创建带用户名水印的excel并保存对应的从查询数据
     *
     * @param dataList 数据
     * @param size     列数量
     * @param userName 用户名
     * @param filePath 存放路径
     * @throws Exception
     */
    public static void createExcel(List<Map> dataList, int size, String userName, String filePath) throws Exception {
        String imgPath = filePath + "/" + userName + ".png";
        String excelFilePath = filePath + "/" + userName + ".xlsx";
        try {
            createWaterMark(userName, imgPath);
            com.spire.xls.Workbook workbook = new com.spire.xls.Workbook();
            Worksheet sheet1 = workbook.getWorksheets().get(0);
            BufferedImage image = ImageIO.read(new File(imgPath));
            sheet1.getPageSetup().setBackgoundImage(image);
            //保存文档
            workbook.saveToFile(excelFilePath, ExcelVersion.Version2007);
            workbook.dispose();
            File file = new File(imgPath);
            file.delete();
        } catch (Exception e) {
            System.out.println("error error error" + e);
        }
        writeExcel(dataList, size, excelFilePath);
    }

    public static void main(String[] args) throws Exception {
        List<Map> list = new ArrayList<>();
        for (int i = 0; i < 100000; i++) {
            Map map = new HashMap();
            map.put("id", 1 + "" + i);
            map.put("name", "1231" + "i");
            list.add(map);
        }
        CreateExcelImg.createExcel(list, 2, "test", "D:\\tt");
    }
}
  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: Here is an example of how you can add a watermark to an Excel file in Java using Apache POI: ``` import java.io.FileInputStream; import java.io.FileOutputStream; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.Font; import org.apache.poi.ss.usermodel.IndexedColors; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.usermodel.WorkbookFactory; import org.apache.poi.xssf.usermodel.XSSFWorkbook; public class WatermarkExcel { public static void main(String[] args) throws Exception { String inputFile = "input.xlsx"; String outputFile = "output.xlsx"; FileInputStream in = new FileInputStream(inputFile); Workbook workbook = WorkbookFactory.create(in); Sheet sheet = workbook.getSheetAt(0); Row row = sheet.createRow(0); Cell cell = row.createCell(0); cell.setCellValue("CONFIDENTIAL"); CellStyle style = workbook.createCellStyle(); Font font = workbook.createFont(); font.setColor(IndexedColors.GREY_50_PERCENT.getIndex()); font.setFontHeightInPoints((short) 48); font.setFontName("Arial"); style.setFont(font); style.setWrapText(true); style.setAlignment(CellStyle.ALIGN_CENTER); style.setVerticalAlignment(CellStyle.VERTICAL_CENTER); sheet.setDefaultColumnWidth(256 * 15); sheet.setDefaultRowHeightInPoints(256 * 15); for (int i = 0; i < sheet.getLastRowNum() + 1; i++) { row = sheet.getRow(i); if (row != null) { for (int j = 0; j < row.getLastCellNum(); j++) { cell = row.getCell(j); if (cell != null) { cell.setCellStyle(style); } } } } FileOutputStream out = new FileOutputStream(outputFile); workbook.write(out); out.close(); workbook.close(); in.close(); } } ``` This code creates a watermark "CONFIDENTIAL" in the first row of the first sheet of the input Excel file. It uses Apache POI library to read the input Excel file, create the watermark and write the output Excel file. The watermark is created with a gray color, 48-point Arial font, centered both horizontally and vertically. ### 回答2: JAVA可以使用Apache POI库来操作Excel文件,实现在Excel中生成水印。 首先,需要导入Apache POI库的相关jar包,并在代码中引入相关的类库。 下面是一个简单的示例代码,展示了如何在Excel文件中生成水印: ``` import org.apache.poi.hssf.usermodel.HSSFClientAnchor; import org.apache.poi.hssf.usermodel.HSSFPatriarch; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.ClientAnchor; import org.apache.poi.ss.usermodel.Picture; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.util.IOUtils; import java.awt.image.BufferedImage; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; public class ExcelWatermarkGenerator { public static void main(String[] args) throws Exception { String excelFilePath = "path/to/your/excel/file.xlsx"; String watermarkImagePath = "path/to/your/watermark/image.png"; InputStream inputStream = new FileInputStream(watermarkImagePath); BufferedImage watermarkImage = ImageIO.read(inputStream); Workbook workbook = new HSSFWorkbook(new FileInputStream(excelFilePath)); HSSFSheet sheet = (HSSFSheet) workbook.getSheetAt(0); HSSFPatriarch patriarch = sheet.createDrawingPatriarch(); HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, 0, 0, 0, 0, 10, 10); anchor.setAnchorType(ClientAnchor.AnchorType.DONT_MOVE_AND_RESIZE); ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream(); ImageIO.write(watermarkImage, "png", byteArrayOut); byte[] bytes = byteArrayOut.toByteArray(); int pictureIndex = workbook.addPicture(bytes, Workbook.PICTURE_TYPE_PNG); Picture picture = patriarch.createPicture(anchor, pictureIndex); picture.resize(); FileOutputStream fileOut = new FileOutputStream(excelFilePath); workbook.write(fileOut); fileOut.close(); System.out.println("水印生成成功!"); } } ``` 以上代码首先载要生成水印Excel文件和水印图片,然后通过Apache POI操作Excel文件并创建一个画图器(HSSFPatriarch)对象。接下来,创建一个锚定器(HSSFClientAnchor)对象来定位水印的位置和大小。将水印图片写入字节数组输出流,并将该字节数组添Excel文件的picture集合中。最后,将修改后的Excel文件保存并关闭。 以上示例代码仅供参考,实际使用时可能需要根据具体需求进行修改。希望对你有所帮助! ### 回答3: 在Java中生成Excel水印的代码可以通过Apache POI库来实现。首先,我们需要导入Apache POI相关的包。 ```java import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.*; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; public class ExcelWatermarkGenerator { public static void main(String[] args) { // 创建新的Excel工作簿 XSSFWorkbook workbook = new XSSFWorkbook(); // 创建工作表 XSSFSheet sheet = workbook.createSheet("Sheet1"); try { // 水印图片 File imageFile = new File("watermark.png"); byte[] byteArray = IOUtils.toByteArray(new FileInputStream(imageFile)); // 创建水印 XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, 0, 0, 3, 5); XSSFDrawing drawing = sheet.createDrawingPatriarch(); XSSFPicture picture = drawing.createPicture(anchor, workbook.addPicture(byteArray, Workbook.PICTURE_TYPE_PNG)); picture.setAnchor(anchor); // 保存Excel文件 FileOutputStream fileOut = new FileOutputStream("watermark_excel.xlsx"); workbook.write(fileOut); fileOut.close(); System.out.println("水印生成成功!"); } catch (IOException e) { e.printStackTrace(); } } } ``` 上述代码中,我们使用了XSSFWorkbook类来创建Excel工作簿,XSSFSheet类来创建工作表。通过文件输入流将水印图片载到字节数组中,然后使用XSSFClientAnchor类和XSSFDrawing类来创建水印并将其添到工作表中。最后,使用FileOutputStream将工作簿保存为Excel文件。 请确保你已经在项目中添了Apache POI的相关依赖,以便代码能够正常运行。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值