HSSF生成EXCEL表格学习分享

  最近这周刚安排了一个需求是生成一个EXCEL表格,目前没有做过生成EXCEL相关的代码开发,就参考项目中下载EXCEL功能的代码,以及百度搜素。最后花了我一天时间终于琢磨透这块内容,然后,觉得这块内容挺有意思,就想着写篇博客记录下学习心得,也方便以后不会了查看自己的博客回顾下,反正代码这东西都是学着忘着,必须得时刻把知识记录下来。所以写一篇拥有自己思路的文章还是很重要的,这样能很快回顾学习知识及找到解决思路。行了,话不多说,开始今天的学习分享了!
  生成EXCEL表格会用到org.apache.poi包,这个包里有一些基本的操作类。首先,先给大家展示下需求中需要生成什么格式的EXCEL表格。
需求表格样式
  从需求分析大可得出表有8列,表的结构分为五部分,第一部分是:“红利通知书退信清单”大标题,此标题占了整个8列;第二部分是:“统计机构”数据区域,此标题占了整个8列;第三部分是:“红利派发区间”数据区域,此标题占了整个8列;第四部分是:标题区域,第五部分是:数据行区域。
  分析完之后就开始根据整理出的分析开发代码。先开发第一部分,代码如下:

				HSSFWorkbook wb = new HSSFWorkbook();
				//第一步:在workbook中添加一个sheet,对应Excel文件中的sheet
				HSSFSheet sheet = wb.createSheet();
				wb.setSheetName(0, excelName, (short) 1);// 给sheet工作簿设置编码格式(short)1
															// 代表UTF-16
				
				//-------------------------表头信息开始--------------------------------
				//第二步:在sheet中添加表头信息
				//第一行:展示红利通知书退信清单大标题
				//设置标题字体
				HSSFFont row1_CellFont = wb.createFont();
				row1_CellFont.setColor(HSSFFont.COLOR_NORMAL);
//				row1_CellFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
				row1_CellFont.setFontHeight((short) 400);
				//设置第一行标题样式
				HSSFCellStyle row1_style = wb.createCellStyle();
				row1_style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
				row1_style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
				row1_style.setBorderTop(HSSFCellStyle.BORDER_THIN);
				row1_style.setBorderRight(HSSFCellStyle.BORDER_THIN);
				row1_style.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 创建一个居中格式
				row1_style.setFont(row1_CellFont);
				
				HSSFRow row1 = sheet.createRow(0);
				//因为有8列,所以循环创建出空的单元格,目的为合并单元格后有边框
				for (int i = 0; i < 8; i++) {
					HSSFCell row1_cell = row1.createCell((short) i);
					if(i == 0) {
						row1.getCell((short) i).setEncoding(HSSFCell.ENCODING_UTF_16);
						row1_cell.setCellValue("红利通知书退信清单");
						row1_cell.setCellStyle(row1_style);
					}else {
						row1_cell.setCellStyle(row1_style);
					}
				}
				//合并单元格
				sheet.addMergedRegion(new Region(0,(short)0,0,(short)7));

  代码中有一处循环是为了解决合并单元格后无边框问题,如果不做这个循环处理合并单元格后会出现无边框问题,(这个问题困扰了我很久,花很长时间上网百度搜索,但是还是没能找到可以解决的方法,这个循环方法是我自己想到后试了下,发现可以解决无边框问题,但是这个方法我感觉不太好,希望大神们评论留言)。
  因为项目中poi包版本较低,所以调用合并单元格时,用的是Region类,Region类使用方法如下:
  跨第1行第1个到第2个单元格的操作为
  sheet.addMergedRegion(new Region(0,(short)0,0,(short)1));
  而目前从POI 3.18开始被Deprecated,在3.20版本中被移除了,所以3.20以前的都有,为了避免这个问题,用  CellRangeAddress代替Region,其用法相同,用法如下:
  CellRangeAddress(int firstRow, int lastRow, int firstCol, int lastCol
  参数:起始行号,终止行号, 起始列号,终止列号

  无边框如图:
无边框
  处理完之后:
在这里插入图片描述
  接下来开发第二部分,同样为了解决无边框问题用到了循环处理代码入下:

				//设置第二行展示信息
				//统计机构:XXXXX
				HSSFCellStyle dataStyle = wb.createCellStyle();
				dataStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);
				dataStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);
				dataStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);
				dataStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);

				HSSFRow row2 = sheet.createRow(1);
				for (int i = 0; i < 8; i++) {
					HSSFCell row2_cell = row2.createCell((short) i);
					if(i == 0) {
						row2.getCell((short) i).setEncoding(HSSFCell.ENCODING_UTF_16);
						row2_cell.setCellValue("统计机构:" + manageCom);
						row2_cell.setCellStyle(dataStyle);
					}else {
						row2_cell.setCellStyle(dataStyle);
					}
				}
				//合并单元格
				sheet.addMergedRegion(new Region(1,(short)0,1,(short)7));

  接下来开发第三部分,同样为了解决无边框问题用到了循环处理代码如下:

				//设置第三行展示信息
				//红利派发区间:XXXX至XXXX
				HSSFRow row3 = sheet.createRow(2);
				for (int i = 0; i < 8; i++) {
					HSSFCell row3_cell = row3.createCell((short) i);
					if(i == 0) {
						row3.getCell((short) i).setEncoding(HSSFCell.ENCODING_UTF_16);
						row3_cell.setCellValue("红利派发区间:" +startDate1+ " 至 "+endDate1);
						row3_cell.setCellStyle(dataStyle);
					}else {
						row3_cell.setCellStyle(dataStyle);
					}
				}
				//合并单元格
				sheet.addMergedRegion(new Region(2,(short)0,2,(short)7));

  接下来开发第四部分,在开发此部分时,参考项目中的代码那个人在生成标题时,写的代码比较繁琐(手写创建了具体哪个单元格),后来也是上网百度时发现很多人写的这种方法又简洁又方便,创建一个数组去存放标题,不管以后增减列还是减少列,只需改动数组存放的内容即可。代码如下:

				//设置第四行数据 标题
				//设置标题字体
				HSSFFont row4_CellFont = wb.createFont();
				row4_CellFont.setColor(HSSFFont.COLOR_RED);
				row4_CellFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
				//设置第四行标题样式
				HSSFCellStyle row4_style = wb.createCellStyle();
				row4_style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
				row4_style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
				row4_style.setBorderTop(HSSFCellStyle.BORDER_THIN);
				row4_style.setBorderRight(HSSFCellStyle.BORDER_THIN);
				row4_style.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 创建一个居中格式
				row4_style.setFont(row4_CellFont);
				
				HSSFRow row4 = sheet.createRow(3);
				//第四行标题名称
				String str[] = {"管理机构","保单号","投保人","红利派发日期","红利派发金额","退信原因","寄送地址","邮编"};
				for (int i = 0; i < str.length; i++) {
					HSSFCell row4_cell = row4.createCell((short) i);
					row4.getCell((short) i).setEncoding(HSSFCell.ENCODING_UTF_16);
					row4_cell.setCellValue(str[i]);
					row4_cell.setCellStyle(row4_style);
				}

  接下来开发第五部分,SSRS类、ListTable类都是公司项目封装的工具类,SSRS类是用来存放数据交互完成后查询到的值,这两个类其实底层都是用Vector实现的。因为目前比较盛行用ArrayList,所以在对查询到的数据进行处理时,大家可以使用ArrayList替代。循环处理数据,将每一行数据存放在一个String数组中,再把数组存放到动态数组中。最后,循环动态数组,展示每一行数据。(因为sheet已经创建了四行,所以直接从第五行开始插入数据行),代码如下:

		SSRS ssrs = exeSQL.execSQL(infoSQL);
		
		ListTable listTable = new ListTable();
		for(int i = 1;i <= ssrs.getMaxRow();i++){
			String[] row = new String[8];//存放一行的数据
		    row[0] = ssrs.GetText(i, 1);
		    row[1] = ssrs.GetText(i,2);
		    row[2] = ssrs.GetText(i, 3);
		    row[3] = ssrs.GetText(i, 4);
		    row[4] = ssrs.GetText(i, 5);
		    row[5] = ssrs.GetText(i, 6);
		    row[6] = ssrs.GetText(i, 7);
		    row[7] = ssrs.GetText(i, 8);
		    listTable.add(row);		
		}
		// 第三步,创建除表头外的数据行单元格,并放数据
		for (int j = 0; j < listTable.size(); j++) {
			//从第五行开始放数据
			HSSFRow row = sheet.createRow(j + 4);
			// 留意ListTable.get(j).length
			for (int k = 0; k < listTable.get(j).length; k++) {
				if (listTable.get(j)[k] != null) {
					// 遍历数据并设置单元格编码
					HSSFCell cellk = row.createCell((short) (k));
					row.getCell((short) (k)).setEncoding(HSSFCell.ENCODING_UTF_16);
					cellk.setCellValue(listTable.get(j)[k]);
					cellk.setCellStyle(dataStyle);
				} else {
					HSSFCell cellk = row.createCell((short) (k));
					cellk.setCellValue(" ");
					cellk.setCellStyle(dataStyle);
				}
			}
		}

  至此表格已经生成完成,信息展示如图:
成果图

发布了1 篇原创文章 · 获赞 3 · 访问量 214

猜你喜欢

转载自blog.csdn.net/weixin_43948095/article/details/104857868
今日推荐