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

2 篇文章 0 订阅

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);
  • 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列结束
含义是:夸两行,不跨列
  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
您可以使用Apache POI库来导出Java的数据到Excel文件。下面是一个简单的示例代码,演示如何将数据导出Excel文件: ```java import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; public class ExcelExporter { public static void main(String[] args) throws IOException { // 创建一个工作簿对象 XSSFWorkbook workbook = new XSSFWorkbook(); // 创建一个工作表对象 Sheet sheet = workbook.createSheet("Sheet1"); // 创建数据 List<List<String>> data = new ArrayList<>(); List<String> row1 = new ArrayList<>(); row1.add("姓名"); row1.add("年龄"); row1.add("性别"); data.add(row1); List<String> row2 = new ArrayList<>(); row2.add("张三"); row2.add("22"); row2.add("男"); data.add(row2); List<String> row3 = new ArrayList<>(); row3.add("李四"); row3.add("25"); row3.add("女"); data.add(row3); // 将数据写入表格 for(int i = 0; i < data.size(); i++) { Row row = sheet.createRow(i); List<String> rowData = data.get(i); for(int j = 0; j < rowData.size(); j++) { Cell cell = row.createCell(j); cell.setCellValue(rowData.get(j)); } } // 将工作簿写入文件 FileOutputStream outputStream = new FileOutputStream("output.xlsx"); workbook.write(outputStream); workbook.close(); outputStream.close(); } } ``` 以上代码将创建一个Excel工作簿,添加一个名为“Sheet1”的工作表,并将数据写入该工作表。最后,将工作簿写入名为“output.xlsx”的文件
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值