POI实战-java开发excel详解(第五章 样式)

时间:2022-10-30 22:12:06

5.POI样式

在Excel应用中,会需要用到各种样式,包括单元格背景色、边框、高度、宽度、内容相对位置、字体格式、字体大小、字体颜色等等。POI提供了一系列的样式,能满足我们一般开发中的需求。

5.1 POI样式相关类

POI设置Excel样式主要通过以下几个相关类:

参数

说明

HSSFCellStyle

POI样式类

HSSFFont

字体样式类

HSSFColor

颜色类

HSSFBorderFormatting

边框样式类

HSSFCellStyle是最基本的样式类。HSSFCellStyle可以直接对上下左右四个边框、内容相对位置、单元格背景色、单元格填充方式、数字格式等进行设置。

HSSFFont是字体样式类,需set到HSSFCellStyle生效。HSSFFont可以设置字体样式、字体大小、字体颜色等。

HSSFColor是颜色类,该类里面有大部分基本颜色属性,提供基本颜色的直接调用。

5.2 单元格边框样式

单元格边框分为上、下、左、右四部分,可以设置其边框的宽度、样式及颜色。边框默认为无边框,若加上边框默认为黑色。

现在为一行10个单元格全部加上边框(细),并设置颜色为红色。

代码片段:

      public static HSSFWorkbook write(InputStream inputStream) throws IOException,ClassNotFoundException{

            //初始一个workbook

            HSSFWorkbook workbook = new HSSFWorkbook(inputStream);

            //获取样式

            HSSFCellStyle style = createCellStyle(workbook);

            //创建一个sheet

            HSSFSheet sheet = workbook.getSheetAt(0);

            HSSFRow row = sheet.createRow(1);

            for(int cellnum = 0; cellnum < 10; cellnum++){

                  HSSFCell cell = row.createCell(cellnum);

                  cell.setCellStyle(style);

            }

            return workbook;

      }

     

      /**

       * 设置单元格的边框(细)且为红色

       * @param workbook

       * @param cellnum

       * @return

       */

      public static HSSFCellStyle createCellStyle(HSSFWorkbook workbook){

            HSSFCellStyle style = workbook.createCellStyle();

            //设置上下左右四个边框宽度

            style.setBorderTop(HSSFBorderFormatting.BORDER_THIN);

            style.setBorderBottom(HSSFBorderFormatting.BORDER_THIN);

            style.setBorderLeft(HSSFBorderFormatting.BORDER_THIN);

            style.setBorderRight(HSSFBorderFormatting.BORDER_THIN);

            //设置上下左右四个边框颜色

            style.setTopBorderColor(HSSFColor.RED.index);

            style.setBottomBorderColor(HSSFColor.RED.index);

            style.setLeftBorderColor(HSSFColor.RED.index);

            style.setRightBorderColor(HSSFColor.RED.index);

           

            return style;

      }

输出结果:

POI实战-java开发excel详解(第五章 样式)

图24

5.3 单元格背景色

单元格背景色填充涉及到填充颜色和填充方式,现以最常用的填充方式填充天蓝色背景。

代码片段:

在上面代码中加入:

//设置单元格背景色

            style.setFillForegroundColor(HSSFColor.SKY_BLUE.index);

            style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);

输出结果:

POI实战-java开发excel详解(第五章 样式)

图25

注:单元格背景色暂不做详解,在附录中我会列出颜色作为开发参考。

5.4 单元格字体格式

字体格式包括书写体、颜色、大小、加粗、斜体、下划线、删除线等。

以下为POI中字体默认属性:

字体属性

Default

书写体

宋体

颜色

黑色

大小

12 有待考证

加粗

斜体

下划线

删除线

 

现将字体设置为幼圆、9px、颜色黄色、加粗、斜体、下划线、删除线作为示例。

代码片段:

在上面代码中加入:

设置数据到单元格代码片段(略)

 

//设置字体格式

            HSSFFont font = workbook.createFont();

            font.setFontName("幼圆");

            font.setFontHeightInPoints((short)9);

            font.setColor(HSSFColor.YELLOW.index);

            font.setBoldweight(font.BOLDWEIGHT_BOLD);

            font.setItalic(true);

            font.setStrikeout(true);

            font.setUnderline((byte)1);

            //将字体格式设置到HSSFCellStyle

            style.setFont(font);

 

输出结果:

POI实战-java开发excel详解(第五章 样式)

图26

5.5 单元格对齐方式

单元格的对齐方式是针对单元格中的内容,单元格中的内容可以靠左、靠右、靠上、靠下、以及垂直居中、水平居中等等。

针对以上各种对齐方式,将目前6.4中输出结果Excel基础上进行微调后操作,将目前基本对齐方式进行展示。

代码片段:

public static HSSFWorkbook write(InputStream inputStream) throws IOException, ClassNotFoundException{

            //初始一个workbook

            HSSFWorkbook workbook = new HSSFWorkbook(inputStream);

            //创建一个sheet

            HSSFSheet sheet = workbook.getSheetAt(0);

            HSSFRow row = sheet.getRow(1);

            for(int cellnum = 0; cellnum < 13; cellnum++){

                  HSSFCell cell = row.getCell(cellnum);

                  //获取样式

                  HSSFCellStyle style =createCellStyle(workbook);

                  cell.setCellStyle(style);

            }

            return workbook;

      }

 

/**

       * 设置单元格的边框(细)且为红色

       * @param workbook

       * @param cellnum

       * @return

       */

      public static HSSFCellStyle createCellStyle(HSSFWorkbook workbook){

            HSSFCellStyle style = workbook.createCellStyle();

            //设置上下左右四个边框宽度

            style.setBorderTop(HSSFBorderFormatting.BORDER_THIN);

            style.setBorderBottom(HSSFBorderFormatting.BORDER_THIN);

            style.setBorderLeft(HSSFBorderFormatting.BORDER_THIN);

            style.setBorderRight(HSSFBorderFormatting.BORDER_THIN);

            //设置上下左右四个边框颜色

            style.setTopBorderColor(HSSFColor.RED.index);

            style.setBottomBorderColor(HSSFColor.RED.index);

            style.setLeftBorderColor(HSSFColor.RED.index);

            style.setRightBorderColor(HSSFColor.RED.index);

            //设置单元格背景色

            style.setFillForegroundColor(HSSFColor.SKY_BLUE.index);

            style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);

            //设置字体格式

            HSSFFont font = workbook.createFont();

            font.setFontName("幼圆");

            font.setFontHeightInPoints((short)9);

            font.setColor(HSSFColor.YELLOW.index);

            font.setBoldweight(font.BOLDWEIGHT_BOLD);

            font.setItalic(true);

            font.setStrikeout(true);

            font.setUnderline((byte)1);

            //将字体格式设置到HSSFCellStyle

            style.setFont(font);

            //设置单元格居中方式

            setCellAlign(style);

            return style;

      }

 

private static void setCellAlign(HSSFCellStyle style){

            switch (num) {

            case 0:

                  //此单元格格式暂不动,默认进行对照

                  num++;

                  break;

            case 1:

                  style.setAlignment(HSSFCellStyle.ALIGN_LEFT);//靠左

                  num++;

                  break;

            case 2:

                  style.setAlignment(HSSFCellStyle.ALIGN_RIGHT);//靠右

                  num++;

                  break;

            case 3:

                  style.setAlignment(HSSFCellStyle.ALIGN_CENTER);//水平居中

                  num++;

                  break;

            case 4:

                  style.setVerticalAlignment(HSSFCellStyle.VERTICAL_TOP);//垂直靠上

                  num++;

                  break;

            case 5:

                  style.setVerticalAlignment(HSSFCellStyle.VERTICAL_BOTTOM);//垂直靠下

                  num++;

                  break;

            case 6:

                  style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);//垂直居中

                  num++;

                  break;

            case 7:

                  style.setVerticalAlignment(HSSFCellStyle.VERTICAL_JUSTIFY);//垂直平铺

                  num++;

                  break;

            case 8:

                  style.setAlignment(HSSFCellStyle.ALIGN_CENTER_SELECTION);//跨列居中

                  num++;

                  break;

            case 9:

                  style.setAlignment(HSSFCellStyle.ALIGN_FILL);//填充

                  num++;

                  break;

            case 10:

                  style.setAlignment(HSSFCellStyle.ALIGN_GENERAL);//普通默认

                  num++;

                  break;

            case 11:

                  style.setAlignment(HSSFCellStyle.ALIGN_JUSTIFY);//两端对齐

                  num++;

                  break;

            case 12:

                  style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);//水平居中且垂直居中

                  style.setAlignment(HSSFCellStyle.ALIGN_CENTER);

                  num++;

                  break;

           

            }

      }

输出结果:

POI实战-java开发excel详解(第五章 样式)

图27

5.6 单元格数字格式化

实际应用开发中,涉及到大量的数据,而各行、各列数据的格式不尽相同,有要求整数型,有要求精确到小数点两位等。解决此类问题一种方式是我们用java将数据进行format后输出,但此种情况导致的问题是输出数据格式为String类型。在这里POI为我们提供了单元格数据格式化的方法。

现将Excel中创建4个单元格依上面的样式,并设置每个单元格的值都是double count =666.1415926;然后进行下面的format。

代码片段:

     

      private static void setCellFormat(HSSFWorkbook workbook, HSSFCellStyle style){

            HSSFDataFormat format = workbook.createDataFormat();

            switch (num) {

            case 0:

                  //此单元格格式暂不动,默认进行对照

                  num++;

                  break;

            case 1:

                  style.setDataFormat(format.getFormat("##.00"));

                  num++;

                  break;

            case 2:

                  style.setDataFormat(format.getFormat("##.000"));

                  num++;

                  break;

            case 3:

                  style.setDataFormat(format.getFormat("###"));

                  num++;

                  break;

            }

      }

 

输出结果:

POI实战-java开发excel详解(第五章 样式)

图28

注:POI中的数字格式化支持四舍五入。

 

5.7单元格宽度与高度

Excel默认的单元格宽度与高度有限,如果我们写入的内容比较长或者需要换行等都涉及到调整宽度与高度。所以需要进行单元格的宽度与高度设置。

这个设置很简单,通过HSSFSheet设置整列的宽度,通过HSSFRow设置正行的高度。POI中宽度、高度设置需要换算,换算单位如下:

 

单位

用法(10px)

高度

15.625

15.625*10

宽度

35.7

35.7*10

现在做一个示范,将Excel的第一、二行设置为高度为40px(两种方法),A列宽度为80px。

代码片段:

      public static HSSFWorkbook write(InputStream inputStream) throws IOException, ClassNotFoundException{

            //初始一个workbook

            HSSFWorkbook workbook = new HSSFWorkbook(inputStream);

            //创建一个sheet

            HSSFSheet sheet = workbook.getSheetAt(0);

            HSSFRow row0 = sheet.createRow(0);

            HSSFRow row1 = sheet.createRow(1);

            //设置行高40px

            row0.setHeight((short)(15.625*40));

            row1.setHeightInPoints((float)40);

            //设置列宽100px

            sheet.setColumnWidth(0, (int)35.7*100);

            return workbook;

      }

 

输出结果:

POI实战-java开发excel详解(第五章 样式)

图29

5.8 合并单元格样式

单元格合并后依然是N个单元格,所以目前在设置合并后的单元格样式时需要分解每一个单元格去设置。

如下图,我们将标题行合并单元格加边框、背景色等样式。

POI实战-java开发excel详解(第五章 样式)

图30

代码片段:

      public static HSSFWorkbook write(InputStream inputStream) throws IOException, ClassNotFoundException{

            //初始一个workbook

            HSSFWorkbook workbook = new HSSFWorkbook(inputStream);

            //获取第一张sheet

            HSSFSheet sheet = workbook.getSheet("合并单元格");

            //准备样式

            Map<String,HSSFCellStyle> styleMap = createCellStyle(workbook);

            //循环所有的合并单元格

            for(int numMR = 0; numMR < sheet.getNumMergedRegions(); numMR++){

                  //获取合并单元格

                  Region region = sheet.getMergedRegionAt(numMR);

                  //获取合并单元格每一个单元格

                  for(int rownum = region.getRowFrom(); rownum <= region.getRowTo(); rownum++){

                        HSSFRow row = sheet.getRow(rownum);

                        for(int cellnum = region.getColumnFrom(); cellnum <= region.getColumnTo(); cellnum++){

                              HSSFCell cell = row.getCell(cellnum);

                              if(cell ==null){

                                    cell = row.createCell(cellnum);

                              }

                              cell.setCellStyle(styleMap.get("titleStyle"));

                        }

                  }

                 

            }

            return workbook;

      }

输出结果:

POI实战-java开发excel详解(第五章 样式)

图31

5.9 Excel样式实例

根据前面7小节的内容,我们将Excel的样式进行规范下的使用与展示。

将下图中的Excel

1)   标题行(第一、二行)填充为背景天蓝色,标题的字体设置为红色、加粗、12px,标题单元格设置为细边框,垂直且水平居中。

2)   内容数据设置为黑色、9px,内容单元格为细边框

3)   总计行填充为背景黄色,字体9px、黑色加粗,单元格为细边框

POI实战-java开发excel详解(第五章 样式)

图32

代码片段:

      public static HSSFWorkbook write(InputStream inputStream) throws IOException, ClassNotFoundException{

            //初始一个workbook

            HSSFWorkbook workbook = new HSSFWorkbook(inputStream);

            //获取第一张sheet

            HSSFSheet sheet = workbook.getSheet("Sheet1");

            //准备样式

            Map<String,HSSFCellStyle> styleMap = createCellStyle(workbook);

            //设置标题行样式

            for(int numMR = 0; numMR < sheet.getNumMergedRegions(); numMR++){

                  //获取合并单元格

                  Region region = sheet.getMergedRegionAt(numMR);

                  //获取合并单元格每一个单元格

                  for(int rownum = region.getRowFrom(); rownum <= region.getRowTo(); rownum++){

                        HSSFRow row = sheet.getRow(rownum);

                        for(int cellnum = region.getColumnFrom(); cellnum <= region.getColumnTo(); cellnum++){

                              HSSFCell cell = row.getCell(cellnum);

                              if(cell ==null){

                                    cell = row.createCell(cellnum);

                              }

                              cell.setCellStyle(styleMap.get("titleStyle"));

                        }

                  }

            }

            //设置内容样式

            for(int cRowNum = 2; cRowNum < sheet.getLastRowNum(); cRowNum++){

                  HSSFRow cRow = sheet.getRow(cRowNum);

                  for(int cCellnum = 0; cCellnum < cRow.getLastCellNum(); cCellnum++){

                        HSSFCell cell = cRow.getCell(cCellnum);

                        cell.setCellStyle(styleMap.get("contentStyle"));

                  }

            }

            //设置总计样式

            HSSFRow cRow = sheet.getRow(sheet.getLastRowNum());

            for(int cCellnum = 0; cCellnum < cRow.getLastCellNum(); cCellnum++){

                  HSSFCell cell = cRow.getCell(cCellnum);

                  if(cell ==null){

                        cell = cRow.createCell(cCellnum);

                  }

                  cell.setCellStyle(styleMap.get("totalStyle"));

            }

            return workbook;

      }

 

public static Map<String, HSSFCellStyle> createCellStyle(HSSFWorkbook workbook){

            Map<String, HSSFCellStyle> styleMap = new HashMap<String, HSSFCellStyle>();

            //标题格式

            HSSFCellStyle titleStyle = workbook.createCellStyle();

            titleStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);

            titleStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);

            setCellBorderStyle(titleStyle);

            setBoldCellFontStyle(workbook, titleStyle, (short)10, HSSFColor.RED.index);

            setBackgroundStyle(titleStyle, HSSFColor.SKY_BLUE.index);

            styleMap.put("titleStyle", titleStyle);

            //内容样式

            HSSFCellStyle contentStyle = workbook.createCellStyle();

            setCellBorderStyle(contentStyle);

            setSimpleCellFontStyle(workbook, contentStyle, (short)9, HSSFColor.BLACK.index);

            styleMap.put("contentStyle", contentStyle);

            //总计样式

            HSSFCellStyle totalStyle = workbook.createCellStyle();

            setCellBorderStyle(totalStyle);

            setBoldCellFontStyle(workbook, totalStyle, (short)9, HSSFColor.BLACK.index);

            setBackgroundStyle(totalStyle, HSSFColor.YELLOW.index);

            styleMap.put("totalStyle", totalStyle);

            return styleMap;

      }

     

     

     

      private static HSSFCellStyle setCellBorderStyle(HSSFCellStyle cellStyle){

            cellStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);

            cellStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);

            cellStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);

            cellStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);

            return cellStyle;

      }

      private static HSSFCellStyle setSimpleCellFontStyle(HSSFWorkbook workbook,HSSFCellStyle cellStyle,short size, short color){

            HSSFFont font = workbook.createFont();

            font.setFontHeightInPoints(size);

            font.setColor(color);

            cellStyle.setFont(font);

            return cellStyle;

      }

      private static HSSFCellStyle setBoldCellFontStyle(HSSFWorkbook workbook,HSSFCellStyle cellStyle,short size, short color){

            HSSFFont font = workbook.createFont();

            font.setBoldweight(font.BOLDWEIGHT_BOLD);

            font.setFontHeightInPoints(size);

            font.setColor(color);

            cellStyle.setFont(font);

            return cellStyle;

      }

     

      private static HSSFCellStyle setBackgroundStyle(HSSFCellStyle cellStyle, short color){

            cellStyle.setFillForegroundColor(color);

            cellStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);

            return cellStyle;

      }

输出结果:POI实战-java开发excel详解(第五章 样式)

图33