java使用poi在excel单元格添加超链接,设置字体颜色

java使用poi在excel单元格添加超链接,设置字体颜色

  • 整体描述
  • 方案描述
  • java实现
    • 1. 引入poi的maven
    • 2. 创建excel单元格配置类
    • 3. 创建excel单元格配置对象
    • 4. 打开excel文件workbook
    • 5. 设置excel单元格
    • 6. 总结

整体描述

产品提的需求,将数据添加到excel中,其中有些图片,需要添加到excel中,这块两种方案,一是将图片直接写入excel中,二是图片和excel放在同一个目录,excel中使用超链接,点击超链接,打开对应的图片。
最后使用方案二,方案一poi也可以实现,文中我也会把实现方式写出来,但是方案一中由于图片全写到excel中,导致excel会很大,查看excel和操作不是很灵活,相比来看方案二就比较灵活,excel只存数据,图片单独存,操作起来很方便,excel看着也很整洁。

方案描述

上述方案二,需要将excel和图片放在同一个目录下,使用相对路径,这样在拷贝操作之后,保证excel中的超链接还可以正常点击,打开超链接的图片。
具体文件目录结构:
–整体文件夹:
----excel文件
----图片文件夹:
----------图片1
----------图片2
拷贝的时候,直接拷贝整体文件夹,即可实现在哪都能正常打开超链接的功能。
还有个地方需要注意:超链接的文字需要修改下字体颜色和样式,设置成蓝色,加下划线。要不看不出来哪个文字有超链接,哪个没有。

java实现

1. 引入poi的maven

poi功能还是很强大的,基本能想到的功能都能通过poi实现。

        
            org.apache.poi
            poi
            3.17
        
        
            org.apache.poi
            poi-ooxml
            3.17
        
        
            org.apache.poi
            ooxml-schemas
            1.1

2. 创建excel单元格配置类

单元格配置类用于设置每个单元格的字体颜色,是否有超链接等。具体看代码和注释吧。

package com.psim.project.patrol.domain;

import lombok.Data;

/**
 * 用于向对应的单元格设置对应的内容
 *
 * @author thcb
 */

@Data
public class ExcelVo {

    /**
     * Excel表的行,Excel中的第一行为此处的第0行
     */
    public int row;

    /**
     * Excel表的列,Excel中的第一列为此处的第0列
     */
    public int column;

    /**
     * 单元格内容
     */
    public String content;

    /**
     * 单元格批注
     */
    public String comment;

    /**
     * 合并单元格参数,起始行
     */
    public int firstRow;

    /**
     * 合并单元格参数,结束行
     */
    public int lastRow;

    /**
     * 合并单元格参数,起始列
     */
    public int firstCol;

    /**
     * 合并单元格参数,结束列
     */
    public int lastCol;

    /**
     * 字体颜色
     */
    public short frontColor;

    /**
     * 超连接
     */
    public String hyperLink = "";

    public ExcelVo(int row, int column, String content) {
        this.row = row;
        this.column = column;
        this.content = content;
        this.comment = "";
        this.firstRow = 0;
        this.lastRow = 0;
        this.firstCol = 0;
        this.lastCol = 0;
        this.frontColor = 0;
        this.hyperLink = "";
    }

    public ExcelVo(int row, int column, String content, short frontColor) {
        this.row = row;
        this.column = column;
        this.content = content;
        this.firstRow = 0;
        this.lastRow = 0;
        this.firstCol = 0;
        this.lastCol = 0;
        this.frontColor = frontColor;
        this.hyperLink = "";
    }

    public ExcelVo(int row, int column, String content, int firstRow, int lastRow, int firstCol, int lastCol) {
        this.row = row;
        this.column = column;
        this.content = content;
        this.firstRow = firstRow;
        this.lastRow = lastRow;
        this.firstCol = firstCol;
        this.lastCol = lastCol;
        this.frontColor = 0;
        this.hyperLink = "";
    }

    public ExcelVo(int row, int column, String content, int firstRow, int lastRow, int firstCol, int lastCol, String hyperLink) {
        this.row = row;
        this.column = column;
        this.content = content;
        this.firstRow = firstRow;
        this.lastRow = lastRow;
        this.firstCol = firstCol;
        this.lastCol = lastCol;
        this.frontColor = 0;
        this.hyperLink = hyperLink;
    }

    public ExcelVo(int row, int column, String content, int firstRow, int lastRow, int firstCol, int lastCol, short frontColor) {
        this.row = row;
        this.column = column;
        this.content = content;
        this.firstRow = firstRow;
        this.lastRow = lastRow;
        this.firstCol = firstCol;
        this.lastCol = lastCol;
        this.frontColor = frontColor;
        this.hyperLink = "";
    }
}

其中字体颜色(frontColor)参数的取值如下,我没找到具体的api描述,各个值代表什么颜色,这个是我自己试出来的,后面应该还有其他颜色,我没往下试…

    /**
     * Excel字体颜色
     */
    interface ExcelColor {

        /**
         * Excel字体颜色:黑色
         */
        short BLACK = 0;

        /**
         * Excel字体颜色:红色
         */
        short RED = 10;

        /**
         * Excel字体颜色:绿色
         */
        short GREEN = 11;

        /**
         * Excel字体颜色:蓝色
         */
        short BLUE = 12;

        /**
         * Excel字体颜色:黄色
         */
        short YELLOW = 13;

        /**
         * Excel字体颜色:紫色
         */
        short PURPLE = 14;

        /**
         * Excel字体颜色:青色
         */
        short CYAN = 15;

        /**
         * Excel字体颜色:棕色
         */
        short BROWN = 16;

        /**
         * Excel字体颜色:深绿
         */
        short DARK_GREEN = 17;

        /**
         * Excel字体颜色:深蓝
         */
        short DARK_BLUE = 18;

        /**
         * Excel字体颜色:深黄
         */
        short DARK_YELLOW = 19;
    }

3. 创建excel单元格配置对象

首先创建ExcelVo对象,/test/test1.jpg为超链接的文件路径

excelVo = new ExcelVo(4, 2, "这是超链接", 4, 6, 2, 2, "/test/test1.jpg");

4. 打开excel文件workbook

File file = new File(filePath);
Workbook workbook = getReportTemplate(file.getAbsolutePath());
setCell(workbook, excelVo);
workbook.write(new FileOutputStream(file));

根据xls和xlsx区分打开的文件,两个格式的创建方式有所区别

/**
     * 获得巡检报表
     *
     * @param filePath 报表文件路径
     */
    public Workbook getReportTemplate(String filePath) {
        Workbook workbook;
        FileInputStream fileInputStream;
        FileOutputStream out = null;
        try {
            fileInputStream = new FileInputStream(filePath);
            if (filePath.endsWith(".xlsx")) {
                FileInputStream fileSystem = new FileInputStream(filePath);
                workbook = new XSSFWorkbook(fileSystem);
                fileSystem.close();
                return workbook;
            }
            if (filePath.endsWith(".xls")) {
                POIFSFileSystem fileSystem = new POIFSFileSystem(fileInputStream);
                workbook = new HSSFWorkbook(fileSystem);
                return workbook;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

5. 设置excel单元格

中间创建excel的步骤略过了,直接调用此方法设置单元格具体样式即可。其中workbook就是生成的excel

/**
     * 根据ExcelVo修改Excel中的指定单元格的值
     *
     * @param ExcelVo Excel单元格
     */
    public void setCell(Workbook workbook, ExcelVo excelVo) {
        Cell cell = createCell(workbook, polRecordTemplateVo);
        if (cell != null) {
            // 单元格样式
            CellStyle cellStyle = workbook.createCellStyle();
            //不直接使用getCellStyle(),用cloneStyleFrom就能实现保持原有样式
            cellStyle.cloneStyleFrom(cell.getCellStyle());
            // 设置单元格字体颜色
            if (excelVo.frontColor != 0) {
                Font font = workbook.createFont();
                font.setColor(excelVo.frontColor);
                cellStyle.setFont(font);
            }
            if (StringUtils.isNotEmpty(excelVo.hyperLink)) {
                // 设置超链接
                CreationHelper createHelper = workbook.getCreationHelper();
                Hyperlink link = createHelper.createHyperlink(HyperlinkType.FILE);
                link.setAddress(excelVo.hyperLink);
                cell.setHyperlink(link);
                // 设置字体
                Font font = workbook.createFont();
                font.setColor(ExcelColor.BLUE);
                font.setUnderline((byte) 1);
                cellStyle.setFont(font);
            }
            // 设置单元格显示内容
            cell.setCellValue(excelVo.content);
            // 设置单元格样式
            cell.setCellStyle(cellStyle);
        }
    }

创建单元格的方法

   /**
     * 创建单元格excelVo
     */
    public Cell createCell(Workbook workbook, ExcelVo excelVo) {
        if (workbook != null) {
            Sheet sheet = workbook.getSheetAt(0);
            if (sheet != null && excelVo != null) {
                Cell cell = null;
                if (excelVo.getFirstCol() == 0
                        && excelVo.getLastCol() == 0
                        && excelVo.getFirstRow() == 0
                        && excelVo.getLastRow() == 0) {
                    // 合并参数都为0,正常创建和对单元格赋值
                    if (sheet.getRow(excelVo.row) != null) {
                        Row row = sheet.getRow(excelVo.row);
                        row.setHeightInPoints(PolPatrolConstants.ROW_HEIGHT);
                        if (row.getCell(excelVo.column) != null) {
                            cell = row.getCell(excelVo.column);
                        } else {
                            cell = row.createCell(excelVo.column);
                        }
                    } else {
                        Row row = sheet.createRow(excelVo.row);
                        row.setHeightInPoints(PolPatrolConstants.ROW_HEIGHT);
                        if (row.getCell(excelVo.column) != null) {
                            cell = row.getCell(excelVo.column);
                        } else {
                            cell = row.createCell(excelVo.column);
                        }
                    }
                } else {
                    // 有不为0的合并参数,需要创建合并单元格
                    CellRangeAddress cellRangeAddress = new CellRangeAddress(
                            excelVo.firstRow,
                            excelVo.lastRow,
                            excelVo.firstCol,
                            excelVo.lastCol);
                    sheet.addMergedRegion(cellRangeAddress);
                    if (sheet.getRow(excelVo.row) != null) {
                        Row row = sheet.getRow(excelVo.row);
                        row.setHeightInPoints(PolPatrolConstants.ROW_HEIGHT);
                        if (row.getCell(excelVo.column) != null) {
                            cell = row.getCell(excelVo.column);
                        } else {
                            cell = row.createCell(excelVo.column);
                        }
                    } else {
                        Row row = sheet.createRow(excelVo.row);
                        row.setHeightInPoints(PolPatrolConstants.ROW_HEIGHT);
                        if (row.getCell(excelVo.column) != null) {
                            cell = row.getCell(excelVo.column);
                        } else {
                            cell = row.createCell(excelVo.column);
                        }
                    }
                }
                return cell;
            } else {
                log.error("setCell:shell is null");
            }
        } else {
            log.error("workbook:workbook is null");
        }
        return null;
    }

6. 总结

仅写出了关键性的代码,需要注意的是合并的时候,一个单元格只能有一个合并的操作,如果合并一个已经合并过的单元格,程序会报错。

你可能感兴趣的:(后端,java,java)