2019-01-21POI生成Excel工具类

POI生成Excel工具类

该工具类中,包含:创建表格(带默认样式)、自定义样式(通过重写 setDefaultStyle和setFirstCellStyle)、合并单元格、宽度自适应等。

/**
 * Excel操作工具类
 */
public class ExcelTools {

    /**
     * 默认的样式, 垂直水平居中、默认换行
     */
    private XSSFCellStyle defaultStyle;

    /**
     * 默认的行首样式
     */
    private XSSFCellStyle firstCellStyle;

    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd hh:mm");

    public XSSFWorkbook createWorkbook() {
        XSSFWorkbook workbook = new XSSFWorkbook();

        XSSFFont defaultFont = workbook.createFont();
        defaultFont.setColor(IndexedColors.BLACK.getIndex());
        defaultFont.setFontHeight(11);
        defaultFont.setFontName("微软雅黑 Light");

        XSSFCellStyle defaultStyle = workbook.createCellStyle();
        defaultStyle.setWrapText(true);
        defaultStyle.setAlignment(HorizontalAlignment.CENTER);
        defaultStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        defaultStyle.setFont(defaultFont);

        XSSFFont font = workbook.createFont();
        font.setColor(IndexedColors.WHITE.getIndex());
        font.setFontHeight(11);
        font.setFontName("微软雅黑 Light");

        XSSFCellStyle firstCellStyle = workbook.createCellStyle();
        firstCellStyle.setAlignment(HorizontalAlignment.CENTER);
        firstCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        firstCellStyle.setFillForegroundColor(IndexedColors.LIGHT_BLUE.getIndex());
        firstCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        firstCellStyle.setFont(font);
        firstCellStyle.setBorderBottom(BorderStyle.THIN);
        firstCellStyle.setBottomBorderColor(IndexedColors.LIGHT_BLUE.getIndex());
        firstCellStyle.setLeftBorderColor(IndexedColors.LIGHT_BLUE.getIndex());
        firstCellStyle.setRightBorderColor(IndexedColors.LIGHT_BLUE.getIndex());

        setDefaultStyle(defaultStyle);
        setFirstCellStyle(firstCellStyle);

        return workbook;
    }

    // 创建页
    public XSSFSheet createSheet(XSSFWorkbook workbook, String sheetName) {
        return workbook.createSheet(sheetName);
    }

    /**
     * 创建表格
     *
     * @param sheet           页 @NotNull
     * @param titles          首行标题 @NotNull
     * @param content         填充的内容 @NotNull
     * @param rowNumber       开始的行号 @NotNull
     * @param colNumber       开始的列号 @NotNull
     * @param customRowHeight 自定义行高
     * @param cellRangeList   需要合并的单元格
     * @param customRowStyle  自定义样式,key 对应行,value 对应样式
     * @param customColWidth  自定义宽度自适应
     */
    @SuppressWarnings("unchecked")
    public void createTable(XSSFSheet sheet, String[] titles, Object[][] content,
                            Integer rowNumber, Integer colNumber,
                            boolean customRowHeight,
                            List<CellRange> cellRangeList,
                            Map<Integer, XSSFCellStyle> customRowStyle,
                            Map<Integer, Integer> customColWidth) {
        // 首行填充
        setFirstRow(sheet, titles, getFirstCellStyle(), rowNumber, colNumber);
        rowNumber++;
        // 设置单元格宽度
        autoWidth(sheet, titles, colNumber, customColWidth);
        // 填充数据
        for (int i = 0; i < content.length; i++) {
            Object[] rowContent = content[i];
            XSSFRow row = sheet.getRow(rowNumber + i) == null ? sheet.createRow(rowNumber + i) : sheet.getRow(rowNumber + i);
            row.setHeight(customRowHeight ? (short) 800 : -1);
            XSSFCellStyle cellStyle = customRowStyle == null || customRowStyle.get(rowNumber + i) == null ?
                    getDefaultStyle() : customRowStyle.get(rowNumber + i);
            for (int j = 0; j < rowContent.length; j++) {
                Object colContent = rowContent[j];
                XSSFCell cell = row.createCell(colNumber + j);
                // 如果是基本数据类型,则转换为字符串填充; 日期转换输出; List转String输出
                if (colContent instanceof Integer || colContent instanceof Double
                        || colContent instanceof String || colContent instanceof Float
                        || colContent instanceof Character || colContent instanceof Byte
                        || colContent instanceof Short || colContent instanceof Boolean
                        || colContent instanceof Long)
                    cell.setCellValue(String.valueOf(colContent));
                else if (colContent instanceof Date)
                    cell.setCellValue(sdf.format(colContent));
                else if (colContent instanceof Iterable)
                    cell.setCellValue(new XSSFRichTextString(String.join(" \n ", (Iterable) colContent)));
                else
                    cell.setCellValue(" - ");
                // 单元格样式
                cell.setCellStyle(cellStyle);
            }
        }

        // 合并单元格
        mergeRegion(sheet, cellRangeList);
    }

    /**
     * 合并单元格
     */
    public static void mergeRegion(XSSFSheet sheet, List<CellRange> cellRangeList) {
        if (cellRangeList == null) return;
        for (CellRange cellRange : cellRangeList) {
            sheet.addMergedRegion(new CellRangeAddress(cellRange.getFirstRow(), cellRange.getLastRow(), cellRange.getFirstCol(), cellRange.getLastCol()));
        }
    }

    /**
     * 无需定制样式和宽度的表格
     */
    public void createTable(XSSFSheet sheet, String[] titles, Object[][] content,
                            Integer rowNumber, Integer colNumber) {
        createTable(sheet, titles, content, rowNumber, colNumber, true, null, null, null);
    }


    /**
     * 填充首行数据
     * 默认按照标题的长度设置单元格宽度
     *
     * @param sheet       页
     * @param cellTitles  标题
     * @param headerStyle 首行样式
     * @param rowNum      起始行
     * @param colNum      起始列
     */
    public static void setFirstRow(XSSFSheet sheet, String[] cellTitles, XSSFCellStyle headerStyle, int rowNum, int colNum) {
        final XSSFRow row = sheet.getRow(rowNum) == null ? sheet.createRow(rowNum) : sheet.getRow(rowNum);
        row.setHeight((short) 800);

        for (String cellName : cellTitles) {
            final Cell cell = row.createCell(colNum++);
            cell.setCellValue(cellName);
            cell.setCellStyle(headerStyle);
        }
    }

    /**
     * 宽度自适应
     *
     * @param sheet       页
     * @param strings     行首
     * @param colNumber   起始列
     * @param customWidth 自定义宽度
     */
    public static void autoWidth(Sheet sheet, String[] strings, Integer colNumber, Map<Integer, Integer> customWidth) {
        for (int s = 0; s < strings.length; s++) {
            int col = colNumber + s;
            if (customWidth != null && customWidth.keySet().contains(col)) {
                sheet.setColumnWidth(col, customWidth.get(col));
            } else {
                sheet.autoSizeColumn(col, true);
                sheet.setColumnWidth(col, sheet.getColumnWidth(col) * 17 / 10);
            }
        }
    }

    public XSSFCellStyle getDefaultStyle() {
        return defaultStyle;
    }

    public void setDefaultStyle(XSSFCellStyle defaultStyle) {
        this.defaultStyle = defaultStyle;
    }

    public XSSFCellStyle getFirstCellStyle() {
        return firstCellStyle;
    }

    public void setFirstCellStyle(XSSFCellStyle firstCellStyle) {
        this.firstCellStyle = firstCellStyle;
    }
}

合并单元格的对象:

/**
 * 需要合并的单元格
 */
@Setter
@Getter
public class CellRange {
    private Integer firstRow;
    private Integer lastRow;
    private Integer firstCol;
    private Integer lastCol;

    private CellRange(Integer firstRow, Integer lastRow, Integer firstCol, Integer lastCol) {
        this.firstRow = firstRow;
        this.lastRow = lastRow;
        this.firstCol = firstCol;
        this.lastCol = lastCol;
    }

    public static CellRange build(Integer firstRow, Integer lastRow, Integer firstCol, Integer lastCol) {
        return new CellRange(firstRow, lastRow, firstCol, lastCol);
    }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容