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的属性,主要包括一些公共范围的设定,如对齐方式、背景颜色、边框等等 

  • 相关阅读:
    Learn Prolog Now 翻译
    Learn Prolog Now 翻译
    Learn Prolog Now 翻译
    Learn Prolog Now 翻译
    Learn Prolog Now 翻译
    Learn Prolog Now 翻译
    Learn Prolog Now 翻译
    Learn Prolog Now 翻译
    Learn Prolog Now 翻译
    Learn Prolog Now 翻译
  • 原文地址:https://www.cnblogs.com/flysand/p/11168404.html
Copyright © 2011-2022 走看看