zoukankan      html  css  js  c++  java
  • poi导出excel并设置打印样式

    以前做的poi导出表格,大多数是导出grid数据列表,这次要求进行各种样式修改,包括冻结行列、合并单元格、背景颜色、边框、自定义行高、列宽 等等,poi本身已经提供了各种的参数方法,这里自己又重新写了一个工具类,对常用的属性设置进行了封装,用以记录。

    需求:

    导出自定义格式的excel表格,包括:字体、颜色、背景、合并单元格、冻结行列、边框

    poi目前最新的已经更新到4.1了,这里还是选用最常用的3.17   

    pom.xml 增加poi jar

         <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi</artifactId>
                <version>3.17</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
            <dependency>
                <groupId>org.apache.poi</groupId>
                <artifactId>poi-ooxml</artifactId>
                <version>3.17</version>
            </dependency>

    自定义工具类

    package com.flysand.utils;
    
    import org.apache.commons.lang3.StringUtils;
    import org.apache.poi.hssf.util.HSSFColor;
    import org.apache.poi.ss.usermodel.*;
    import org.apache.poi.ss.util.CellRangeAddress;
    import org.apache.poi.ss.util.RegionUtil;
    import org.apache.poi.xssf.streaming.SXSSFWorkbook;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.util.CollectionUtils;
    
    import java.util.List;
    import java.util.Map;
    
    /**
     * 用于生成带格式的excel
     *
     * @author flysand
     **/
    public class CusExcelUtil {
    
        private static final Logger logger = LoggerFactory.getLogger(CusExcelUtil.class);
    
        /**
         * 行高像素乘数 row.setHeight = 15 * x  x为实际excel表格高度(px)
         */
        private static final short HEIGHT_POINTS_MULTI = 15;
        /**
         * 列宽像素乘数 sheet.setColumnWeight(index, 32 * y) y为实际excel表格单元格宽度
         */
        private static final short WEIGHT_POINTS_MULTI = 32;
    
    
        /**
         * 创建工作簿
         *
         * @param sheetList
         * @return
         */
        public static Workbook createWorkBook(List<CusSheet> sheetList, int rowSize) {
    
            // 创建空工作簿 直接创建xlsx类型 SXSSF 默认内存最大行数为100 即超过100行,之前的行就刷新到磁盘上,这时再获取之前的行会报错,需动态设置
         rowSize = rowSize == 0 ? -1 : rowSize;
    Workbook workbook = new SXSSFWorkbook(rowSize); // 遍历sheet,创建sheet页 if (CollectionUtils.isEmpty(sheetList)) { logger.error("未传入sheet数据"); return workbook; } for (int s = 0; s < sheetList.size(); s++) { CusSheet cusSheet = sheetList.get(s); // 创建sheet String sheetName = StringUtils.isBlank(cusSheet.getSheetName()) ? "sheet" + s : cusSheet.getSheetName(); Sheet sheet = workbook.createSheet(sheetName); // 创建行 List<CusRow> rowList = cusSheet.getRowList(); if (CollectionUtils.isEmpty(rowList)) { logger.debug("当前sheet没有数据:{}", sheetName); continue; } logger.debug("开始生成sheet - {}", sheetName); for (int r = cusSheet.getTopSpace(); r < rowList.size() + cusSheet.getTopSpace(); r++) { CusRow cusRow = rowList.get(r - cusSheet.getTopSpace()); Row row = sheet.createRow(r); // 设置行高 if (cusRow.getHeight() != 0) { row.setHeight((short) (HEIGHT_POINTS_MULTI * cusRow.getHeight())); } // 空行跳过 if (cusRow.isSpaceRow()) { // 空行默认设置为30 if (cusRow.getHeight() == 0) { row.setHeight((short) (HEIGHT_POINTS_MULTI * 30)); } logger.debug("当前row{}没有数据,为空行", r); continue; } // 创建单元格 List<ColumnCell> columnCellList = cusRow.getColumnCellList(); if (CollectionUtils.isEmpty(columnCellList)) { logger.debug("row{}未设置为空行,但没有列数据", r); continue; } // 设置第一行的每个单元格宽度 /*Map<Integer, Integer> columnWidthMap = null; if (!CollectionUtils.isEmpty(cusSheet.getColumnWidthMap()) && r == cusSheet.getTopSpace()) { columnWidthMap = cusSheet.getColumnWidthMap(); }*/ Map<Integer, Integer> columnWidthMap = cusSheet.getColumnWidthMap(); for (int c = cusSheet.getLeftSpace(); c < columnCellList.size() + cusSheet.getLeftSpace(); c++) { // 列数据 ColumnCell columnCell = columnCellList.get(c - cusSheet.getLeftSpace()); if (columnWidthMap != null && columnWidthMap.get(c) != 0) { // 设置列宽 int width = columnWidthMap.get(c); logger.debug("行{}列{}宽度为{}", r, c, width); sheet.setColumnWidth(c, WEIGHT_POINTS_MULTI * width); } // 创建单元格 Cell cell = row.createCell(c); // 设置样式和值 cell.setCellValue(columnCell.getCellValue()); cell.setCellStyle(createCellStyle(workbook, cusSheet, cusRow, columnCell)); } } // 合并单元格 if (!CollectionUtils.isEmpty(cusSheet.getMergeCellList())) { logger.debug("设置sheet - {} - 合并单元格,个数{}", sheetName, cusSheet.getMergeCellList().size()); for (MergeCell mergeCell : cusSheet.getMergeCellList()) { // 添加合并单元格 sheet.addMergedRegion(mergeCell); // 设置单元格边框样式 BorderStyle borderStyle = null; // 单元格 先取单元格自己设置 if (mergeCell.getBorderStyle() != null) { borderStyle = mergeCell.getBorderStyle(); } else if (cusSheet.getBorderRange() != null) { switch (cusSheet.getBorderRange()) { case SHEET: borderStyle = cusSheet.getBorderStyle(); break; case CELL: borderStyle = mergeCell.getBorderStyle(); break; default: } } HSSFColor borderColor = null; if (cusSheet.getBorderColorRange() != null) { switch (cusSheet.getBorderColorRange()) { case SHEET: borderColor = cusSheet.getBorderColor(); break; case CELL: borderColor = mergeCell.getBorderColor(); break; default: } } if (borderStyle != null) { RegionUtil.setBorderTop(borderStyle, mergeCell, sheet); RegionUtil.setBorderBottom(borderStyle, mergeCell, sheet); RegionUtil.setBorderLeft(borderStyle, mergeCell, sheet); RegionUtil.setBorderRight(borderStyle, mergeCell, sheet); } if (borderColor != null) { RegionUtil.setTopBorderColor(borderColor.getIndex(), mergeCell, sheet); RegionUtil.setBottomBorderColor(borderColor.getIndex(), mergeCell, sheet); RegionUtil.setLeftBorderColor(borderColor.getIndex(), mergeCell, sheet); RegionUtil.setRightBorderColor(borderColor.getIndex(), mergeCell, sheet); } } } // 设置冻结行列 FreezePane freezePane = cusSheet.getFreezePane(); if (freezePane != null) { logger.debug("sheet-{}-存在冻结区域,设置冻结行列"); sheet.createFreezePane(freezePane.getColumn(), freezePane.getRow(), freezePane.getDisplayColumn(), freezePane.getDisplayRow()); } // 设置打印样式 -- 横向打印 A4纸大小 sheet.getPrintSetup().setLandscape(cusSheet.isLandScape()); sheet.getPrintSetup().setPaperSize(PrintSetup.A4_PAPERSIZE); // 设置重复行 if (cusSheet.getRepeatRow() != null) { sheet.setRepeatingRows(cusSheet.getRepeatRow()); } logger.debug("sheet -{} - 数据生成完成", sheetName); } logger.debug("工作簿生成完毕"); return workbook; } /** * 创建单元格样式 * * @param workbook 工作簿 * @param cusSheet sheet数据 * @param cusRow 行数据 * @param columnCell 列数据 * @return */ public static CellStyle createCellStyle(Workbook workbook, CusSheet cusSheet, CusRow cusRow, ColumnCell columnCell) { // 创建样式 CellStyle cellStyle = workbook.createCellStyle(); // 创建字体 Font font = workbook.createFont(); font.setFontName(columnCell.getFontFamily()); font.setFontHeightInPoints(columnCell.getFontSize()); // 字体颜色 if (columnCell.getFontColor() != null) { font.setColor(columnCell.getFontColor().getIndex()); } // 设置字体样式 if (!CollectionUtils.isEmpty(columnCell.getCellFontEnumList())) { for (CellFontEnum cellFontEnum : columnCell.getCellFontEnumList()) { switch (cellFontEnum) { case ITALIC: font.setItalic(Boolean.TRUE); break; case BOLD: font.setBold(Boolean.TRUE); break; case UNDERLINE: font.setUnderline(Font.U_SINGLE); break; case D_UNDERLINE: font.setUnderline(Font.U_DOUBLE); break; case STRIKEOUT: font.setStrikeout(Boolean.TRUE); break; default: } } } cellStyle.setFont(font); // 设置是否自动换行 -- 默认自动换行 cellStyle.setWrapText(cusSheet.isWrapText()); // 设置对齐方式 -- 默认不设置对齐方式 即:全部左上对齐 if (cusSheet.getAlignRange() != null) { switch (cusSheet.getAlignRange()) { case SHEET: cellStyle.setAlignment(cusSheet.getHorizontalAlignment() == null ? HorizontalAlignment.LEFT : cusSheet.getHorizontalAlignment()); cellStyle.setVerticalAlignment(cusSheet.getVerticalAlignment() == null ? VerticalAlignment.TOP : cusSheet.getVerticalAlignment()); break; case ROW: cellStyle.setAlignment(cusRow.getHorizontalAlignment() == null ? HorizontalAlignment.LEFT : cusRow.getHorizontalAlignment()); cellStyle.setVerticalAlignment(cusRow.getVerticalAlignment() == null ? VerticalAlignment.TOP : cusRow.getVerticalAlignment()); break; case CELL: cellStyle.setAlignment(columnCell.getHorizontalAlignment() == null ? HorizontalAlignment.LEFT : columnCell.getHorizontalAlignment()); cellStyle.setVerticalAlignment(columnCell.getVerticalAlignment() == null ? VerticalAlignment.TOP : columnCell.getVerticalAlignment()); break; case DEFAULT: cellStyle.setAlignment(HorizontalAlignment.CENTER); cellStyle.setVerticalAlignment(VerticalAlignment.CENTER); default: } } // 设置背景颜色 HSSFColor color = null; if (cusSheet.getBgColorRange() != null) { switch (cusSheet.getBgColorRange()) { case ROW: color = cusRow.getBgColor(); break; case CELL: color = columnCell.getBgColor(); break; default: } } if (color != null) { // 设置前景色 -- 背景色 setFillBackgroundColor 设置后显示不出来,所以设置背景色 cellStyle.setFillForegroundColor(color.getIndex()); // 填充类型:实线 cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); } // 设置边框样式 BorderStyle borderStyle = null; if (cusSheet.getBorderRange() != null) { switch (cusSheet.getBorderRange()) { case SHEET: borderStyle = cusSheet.getBorderStyle(); break; case CELL: borderStyle = columnCell.getBorderStyle(); break; default: } } if (borderStyle != null) { cellStyle.setBorderTop(borderStyle); cellStyle.setBorderBottom(borderStyle); cellStyle.setBorderLeft(borderStyle); cellStyle.setBorderRight(borderStyle); } HSSFColor borderColor = null; if (cusSheet.getBorderColorRange() != null) { switch (cusSheet.getBorderColorRange()) { case SHEET: borderColor = cusSheet.getBorderColor(); break; case CELL: borderColor = columnCell.getBorderColor(); break; default: } } if (borderColor != null) { cellStyle.setTopBorderColor(borderColor.getIndex()); cellStyle.setBottomBorderColor(borderColor.getIndex()); cellStyle.setLeftBorderColor(borderColor.getIndex()); cellStyle.setRightBorderColor(borderColor.getIndex()); } return cellStyle; } /** * 样式范围,即当前属性的作用域,优先级从上到下覆盖 */ public enum CusStyleRange { /** * 适用于整个sheet */ SHEET, /** * 适用于整行 */ ROW, /** * 适用于单元格 */ CELL, /** * 默认 */ DEFAULT; } /** * 单元格字体样式 */ public enum CellFontEnum { /** * 斜体 */ ITALIC, /** * 加粗 */ BOLD, /** * 下划线 */ UNDERLINE, /** * 双下划线 */ D_UNDERLINE, /** * 删除线 */ STRIKEOUT, } /** * 合并单元格 */ public static class MergeCell extends CellRangeAddress { /** * 边框样式 */ private BorderStyle borderStyle; /** * 边框颜色 */ private HSSFColor borderColor; /** * 合并单元格起始行列 从0开始 * * @param firstRow 合并起始行 * @param lastRow 合并截止行 * @param firstCol 合并起始列 * @param lastCol 合并截止列 * @param borderStyle 边框样式 * @param borderColor 边框颜色 */ public MergeCell(int firstRow, int lastRow, int firstCol, int lastCol, BorderStyle borderStyle, HSSFColor borderColor) { super(firstRow, lastRow, firstCol, lastCol); this.borderStyle = borderStyle; this.borderColor = borderColor; } public BorderStyle getBorderStyle() { return borderStyle; } public void setBorderStyle(BorderStyle borderStyle) { this.borderStyle = borderStyle; } public HSSFColor getBorderColor() { return borderColor; } public void setBorderColor(HSSFColor borderColor) { this.borderColor = borderColor; } } /** * 冻结面板 */ public static class FreezePane { /** * 冻结列 从1开始 如A列为1,0为不冻结 */ private int column; /** * 冻结行 从1开始 0为不冻结 */ private int row; /** * 从冻结列开始数的列数,滚轮显示的第一列 从1开始,如 冻结B列 从2开始 即直接显示D,C列隐藏在滚轮里 */ private int displayColumn; /** * 从冻结行开始数的行数 */ private int displayRow; public FreezePane() { } public FreezePane(int column, int row, int displayColumn, int displayRow) { this.column = column; this.row = row; this.displayColumn = displayColumn; this.displayRow = displayRow; } public int getColumn() { return column; } public void setColumn(int column) { this.column = column; } public int getRow() { return row; } public void setRow(int row) { this.row = row; } public int getDisplayColumn() { return displayColumn; } public void setDisplayColumn(int displayColumn) { this.displayColumn = displayColumn; } public int getDisplayRow() { return displayRow; } public void setDisplayRow(int displayRow) { this.displayRow = displayRow; } } /** * 自定义sheet */ public static class CusSheet { /** * sheet名称 */ private String sheetName; /** * 空出的行数 */ private short topSpace = 0; /** * 空出的列数 */ private short leftSpace = 0; /** * 是否横向打印 默认false 纵向打印 */ private boolean landScape; /** * 重复行 -- 一般做数据明细标题行使用 */ private MergeCell repeatRow; /** * 边框范围 SHEET CELL */ private CusStyleRange borderRange; /** * 边框颜色范围 SHEET CELL */ private CusStyleRange borderColorRange; /** * 对齐方式范围 SHEET ROW CELL */ private CusStyleRange alignRange; /** * 背景颜色范围 ROW CELL */ private CusStyleRange bgColorRange; /** * 水平对齐方式 */ private HorizontalAlignment horizontalAlignment; /** * 垂直对齐方式 */ private VerticalAlignment verticalAlignment; /** * 是否换行 -- 放到sheet上进行全局配置 不允许一部分单元格自动换行,一部分不自动换行 */ private boolean wrapText = true; private List<CusRow> rowList; private List<MergeCell> mergeCellList; /** * 冻结面板 */ private FreezePane freezePane; /** * 列宽集合 */ private Map<Integer, Integer> columnWidthMap; /** * 边框样式 */ private BorderStyle borderStyle; /** * 边框颜色 */ private HSSFColor borderColor; public String getSheetName() { return sheetName; } public void setSheetName(String sheetName) { this.sheetName = sheetName; } public short getTopSpace() { return topSpace; } public void setTopSpace(short topSpace) { this.topSpace = topSpace; } public short getLeftSpace() { return leftSpace; } public void setLeftSpace(short leftSpace) { this.leftSpace = leftSpace; } public boolean isLandScape() { return landScape; } public void setLandScape(boolean landScape) { this.landScape = landScape; } public MergeCell getRepeatRow() { return repeatRow; } public void setRepeatRow(MergeCell repeatRow) { this.repeatRow = repeatRow; } public List<CusRow> getRowList() { return rowList; } public void setRowList(List<CusRow> rowList) { this.rowList = rowList; } public List<MergeCell> getMergeCellList() { return mergeCellList; } public void setMergeCellList(List<MergeCell> mergeCellList) { this.mergeCellList = mergeCellList; } public CusStyleRange getBorderRange() { return borderRange; } public void setBorderRange(CusStyleRange borderRange) { this.borderRange = borderRange; } public CusStyleRange getBorderColorRange() { return borderColorRange; } public void setBorderColorRange(CusStyleRange borderColorRange) { this.borderColorRange = borderColorRange; } public CusStyleRange getAlignRange() { return alignRange; } public void setAlignRange(CusStyleRange alignRange) { this.alignRange = alignRange; } public CusStyleRange getBgColorRange() { return bgColorRange; } public void setBgColorRange(CusStyleRange bgColorRange) { this.bgColorRange = bgColorRange; } public HorizontalAlignment getHorizontalAlignment() { return horizontalAlignment; } public void setHorizontalAlignment(HorizontalAlignment horizontalAlignment) { this.horizontalAlignment = horizontalAlignment; } public VerticalAlignment getVerticalAlignment() { return verticalAlignment; } public void setVerticalAlignment(VerticalAlignment verticalAlignment) { this.verticalAlignment = verticalAlignment; } public FreezePane getFreezePane() { return freezePane; } public void setFreezePane(FreezePane freezePane) { this.freezePane = freezePane; } public Map<Integer, Integer> getColumnWidthMap() { return columnWidthMap; } public void setColumnWidthMap(Map<Integer, Integer> columnWidthMap) { this.columnWidthMap = columnWidthMap; } public boolean isWrapText() { return wrapText; } public void setWrapText(boolean wrapText) { this.wrapText = wrapText; } public BorderStyle getBorderStyle() { return borderStyle; } public void setBorderStyle(BorderStyle borderStyle) { this.borderStyle = borderStyle; } public HSSFColor getBorderColor() { return borderColor; } public void setBorderColor(HSSFColor borderColor) { this.borderColor = borderColor; } } /** * 自定义行 */ public static class CusRow { /** * 是否为空行 */ private boolean spaceRow; /** * 行高 */ private short height; /** * 对齐方式,sheet中对齐方式设置为ROW时生效 */ private HorizontalAlignment horizontalAlignment; private VerticalAlignment verticalAlignment; /** * 背景颜色 -- sheet中颜色范围设置为ROW时生效 */ private HSSFColor bgColor; private List<ColumnCell> columnCellList; public boolean isSpaceRow() { return spaceRow; } public void setSpaceRow(boolean spaceRow) { this.spaceRow = spaceRow; } public short getHeight() { return height; } public void setHeight(short height) { this.height = height; } public HorizontalAlignment getHorizontalAlignment() { return horizontalAlignment; } public void setHorizontalAlignment(HorizontalAlignment horizontalAlignment) { this.horizontalAlignment = horizontalAlignment; } public VerticalAlignment getVerticalAlignment() { return verticalAlignment; } public void setVerticalAlignment(VerticalAlignment verticalAlignment) { this.verticalAlignment = verticalAlignment; } public HSSFColor getBgColor() { return bgColor; } public void setBgColor(HSSFColor bgColor) { this.bgColor = bgColor; } public List<ColumnCell> getColumnCellList() { return columnCellList; } public void setColumnCellList(List<ColumnCell> columnCellList) { this.columnCellList = columnCellList; } } /** * 自定义单元格 */ public static class ColumnCell { private String cellValue; private String fontFamily = "宋体"; /** * 字体颜色 */ private HSSFColor fontColor = HSSFColor.HSSFColorPredefined.BLACK.getColor(); private short fontSize = 11; private List<CellFontEnum> cellFontEnumList; /** * 对齐方式,sheet中对齐方式设置为CELL时生效 */ private HorizontalAlignment horizontalAlignment; private VerticalAlignment verticalAlignment; private BorderStyle borderStyle; private HSSFColor borderColor; /** * sheet中颜色范围设置为CELL时生效 */ private HSSFColor bgColor; public ColumnCell() { } public ColumnCell(String cellValue) { this.cellValue = cellValue; } /** * 指定字体大小和单元格对齐方式 * * @param cellValue * @param fontSize * @param horizontalAlignment * @param verticalAlignment */ public ColumnCell(String cellValue, short fontSize, HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment) { this.cellValue = cellValue; this.fontSize = fontSize; if (horizontalAlignment != null) { this.horizontalAlignment = horizontalAlignment; } if (verticalAlignment != null) { this.verticalAlignment = verticalAlignment; } } public ColumnCell(String cellValue, HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment) { this.cellValue = cellValue; if (horizontalAlignment != null) { this.horizontalAlignment = horizontalAlignment; } if (verticalAlignment != null) { this.verticalAlignment = verticalAlignment; } } public String getCellValue() { return cellValue; } public void setCellValue(String cellValue) { this.cellValue = cellValue; } public String getFontFamily() { return fontFamily; } public void setFontFamily(String fontFamily) { this.fontFamily = fontFamily; } public HSSFColor getFontColor() { return fontColor; } public void setFontColor(HSSFColor fontColor) { this.fontColor = fontColor; } public short getFontSize() { return fontSize; } public void setFontSize(short fontSize) { this.fontSize = fontSize; } public List<CellFontEnum> getCellFontEnumList() { return cellFontEnumList; } public void setCellFontEnumList(List<CellFontEnum> cellFontEnumList) { this.cellFontEnumList = cellFontEnumList; } public HorizontalAlignment getHorizontalAlignment() { return horizontalAlignment; } public void setHorizontalAlignment(HorizontalAlignment horizontalAlignment) { this.horizontalAlignment = horizontalAlignment; } public VerticalAlignment getVerticalAlignment() { return verticalAlignment; } public void setVerticalAlignment(VerticalAlignment verticalAlignment) { this.verticalAlignment = verticalAlignment; } public BorderStyle getBorderStyle() { return borderStyle; } public void setBorderStyle(BorderStyle borderStyle) { this.borderStyle = borderStyle; } public HSSFColor getBorderColor() { return borderColor; } public void setBorderColor(HSSFColor borderColor) { this.borderColor = borderColor; } public HSSFColor getBgColor() { return bgColor; } public void setBgColor(HSSFColor bgColor) { this.bgColor = bgColor; } } }

    参数为自定义的list集合,需要设置每个sheet的属性,主要包括一些公共范围的设定,如对齐方式、背景颜色、边框等等 

  • 相关阅读:
    金融培训心得:银行客户经理10大不专业表现
    团队中的八类乞丐:你不改变,谁也救不了你!
    笔记本分类大全
    拆轮子 笔记
    spacemacs 自定义配置 笔记
    Fedora 25 安装搜狗输入法
    spark 配置使用
    Anaconda 仓库的镜像
    vscode vim配置
    使用Vim normal 命令 修改可视块区域
  • 原文地址:https://www.cnblogs.com/flysand/p/11168404.html
Copyright © 2011-2022 走看看