java中Excel导出模板(跨行跨列导出)

跳转地址:点我
java中Excel导出模板(跨行跨列导出)
在这里插入图片描述
这个地方看似不难,实际后台很复杂,数据的来源也复杂,并不好处理。但是这不是让我纠结的地方。
我纠结的地方是,表头的跨行跨列,而且有的列还是动态的。

有了技术问题的时候,捋捋思路后,如果还解决不了,那可能是要去百度了,因为毕竟是在工作,不要耽误时间,赶紧解决问题。

七拼八凑整理了一套方法(后边附上代码),实现的小时如下:
在这里插入图片描述
就这样,表头的问题就解决了。
代码:

package com.incon.project.xmsb.controller;

import java.io.FileOutputStream;
import java.io.IOException;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.util.Region;

/**

  • @方法描述 java中excel导出包括合并单元格和单元格样式

  • @初次开发 平传胜

  • @开发日期 2019年4月23日下午2:21:05
    */
    public class TestPoi2 {
    public static void main(String[] args) throws IOException {
    try {
    HSSFWorkbook wb = new HSSFWorkbook();
    HSSFSheet sheet = wb.createSheet(“POI-Excel测试”);

     	HSSFCellStyle style = wb.createCellStyle(); // 样式对象
     	style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 垂直
     	style.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 水平
     	
     	//因为需求一共有3行数据,这里就先创建3个行的空数据,之后分别对这3个行数据进行操作
     	HSSFRow row1 = sheet.createRow((short) 0);//先创建第一行空数据
     	HSSFRow row2 = sheet.createRow((short) 1);//先创建第二行空数据
     	HSSFRow row3 = sheet.createRow((short) 2);//先创建第三行空数据
     	
     	/** 设置第一行的数据 */
     	// 四个参数分别是:起始行,起始列,结束行,结束列
     	//第1个格子,夸3行
     	sheet.addMergedRegion(new Region(0, (short) 0, 2, (short) 0));
     	HSSFCell ce1 = row1.createCell((short) 0);
     	ce1.setCellValue("序号");//表格的第一行第一列显示的数据
     	ce1.setCellStyle(style);//样式,居中
     	
     	//第2个格子,夸3行
     	sheet.addMergedRegion(new Region(0, (short) 1, 2, (short) 1));
     	HSSFCell ce2 = row1.createCell((short) 1);
     	ce2.setCellValue("所在学院");
     	ce2.setCellStyle(style);
     	
     	//第3个格子,夸3行
     	sheet.addMergedRegion(new Region(0, (short) 2, 2, (short) 2));
     	HSSFCell ce3 = row1.createCell((short) 2);
     	ce3.setCellValue("教师姓名");
     	ce3.setCellStyle(style);
     	
     	//第4个格子,夸14列
     	sheet.addMergedRegion(new Region(0, (short) 3, 0, (short) 16));
     	HSSFCell ce4 = row1.createCell((short) 3);
     	ce4.setCellValue("近几年课堂教学学时");
     	ce4.setCellStyle(style);
     	
     	
     	/** 设置第二行的数据 */
     	
     	//第5个格子,夸2行
     	sheet.addMergedRegion(new Region(1, (short) 3, 2, (short) 3));
     	HSSFCell ce5 = row2.createCell((short) 3);
     	ce5.setCellValue("课程名称");
     	ce5.setCellStyle(style);
     	
     	//第6个格子,夸2行
     	sheet.addMergedRegion(new Region(1, (short) 4, 2, (short) 4));
     	HSSFCell ce6 = row2.createCell((short) 4);
     	ce6.setCellValue("课程性质");
     	ce6.setCellStyle(style);
     	
     	//生成动态的那些行列值
     	for (int i = 0; i < 6; i++) {
     		// 计算从那个单元格跨到那一格
     		int row2_cell_1 = 4;//第二行的第1个值(其实是第4个值,因为前面已经有3列被占用,所以要从第四列开始)
     		int row2_cell_2 = 5;//第二行的第2个值(其实是第5个值,因为前面已经有4列被占用,所以要从第四列开始)
     		if (i > 0) {
     			row2_cell_1 = (i * 2 + 4);//每行夸两列
     			row2_cell_2 = (i * 2 + 4 + 1);// +1表示下一列的值的取值范围
     		}
     		
     		// 单元格合并
     		sheet.addMergedRegion(new Region(1, (short) (row2_cell_1 + 1), 1, (short) (row2_cell_2 + 1)));
     		HSSFCell cell = row2.createCell((short) (row2_cell_1 + 1));
     		cell.setCellValue("201" + i + "秋季"); // 跨单元格显示的数据
     		cell.setCellStyle(style);
     		
     		/** 设置第三行的数据 */
     		// 不跨单元格显示的数据,如:分两行,上一行分别两格为一格,下一行就为两格,“课时”,“人数”
     		sheet.addMergedRegion(new Region(0, (short) (row2_cell_1 + 1), 0, (short) (row2_cell_2 + 1)));
     		HSSFCell cell1 = row3.createCell((short) row2_cell_2);
     		HSSFCell cell2 = row3.createCell((short) (row2_cell_2 + 1));
     		cell1.setCellValue("课时");
     		cell1.setCellStyle(style);
     		cell2.setCellValue("人数");
     		cell2.setCellStyle(style);
     	}
     	//将文件生成到 d 盘根目录下,取名为 workbook.xls
     	FileOutputStream fileOut = new FileOutputStream("d:/workbook.xls");
     	wb.write(fileOut);//写出文件
     	fileOut.close();//关闭流
     	System.out.print("Excel文件已成功导出,请到D盘根目录查找 workbook.xls 文件!");
     } catch (Exception ex) {
     	ex.printStackTrace();
     }
    

    }
    }

创建格子的代码说明:
在这里插入图片描述
其实光看代码就可以了。但是这里有个比较麻烦的地方,需要我们理解。就是 每次计算行的格子的起始位置的问题 很容易错,还不好找原因,下面上图整理下:
在这里插入图片描述
说明:

1,红黄蓝,分别对应代码中的第一行(row1)、第二行(row2)、第三行(row3)的数据的获取;
2,行号、列号,在程序里取值的时候都是从0开始的;
3,编号为圈4的那个大格子,是第一行的第四个值,所以取值的方法是:
//第4个格子,夸14列
sheet.addMergedRegion(new Region(0, (short) 3, 0, (short) 16));
HSSFCell ce4 = row1.createCell((short) 3);
ce4.setCellValue(“近几年课堂教学学时”);
ce4.setCellStyle(style);
1
2
3
4
5
4,编号从21-28的都是第二行数据。这里取值就要注意了。因为其实,21号是第二行的第4列了。所以取第21号的数据的时候代码应是:
sheet.addMergedRegion(new Region(1, (short) 3, 2, (short) 3));
HSSFCell ce5 = row2.createCell((short) 3);
ce5.setCellValue(“课程名称”);
ce5.setCellStyle(style);

代码解释:

new Region(1, (short) 3, 2, (short) 3)
表示:第2行开始,第4列开始,第3行结束,第4列结束
含义是:夸两行,不跨列

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值