利用Apache POI实现随机排座
需求:对excel表格中的学生的座位进行随机分配。
一、解决思路
- 创建 Student 实体类:定义一个 Student 类,包含一个 name 属性,用于表示学生姓名。
- 读取 Excel 中的学生姓名并创建对象:使用Apache POI,读取 Excel 文件中的学生姓名,并使用构造函数创建相应的 Student 对象。
- 将学生对象放入 List 集合:创建一个 List 集合,将读取到的学生对象添加到集合中。
- 对学生集合进行操作,进行排座操作,并且返回一个二位数组。
- 将排座结果的二维数组导出为 Excel 格式的文件。
二、具体实现
-
导入依赖
<dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>5.0.0</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>5.0.0</version> </dependency> <!-- 如果你的POI是4.1.2版本,那么它需要的XMLBeans版本是3.1.0。如果你的POI是5.0.0版本,那么它需要的XMLBeans版本是4.0.0。--> <dependency> <groupId>org.apache.xmlbeans</groupId> <artifactId>xmlbeans</artifactId> <version>4.0.0</version> </dependency><dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-collections4</artifactId> <version>4.4</version> </dependency> <!--如果导入上面依赖报错还可以添加下面依赖--> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-compress</artifactId> <version>1.21</version> <!-- 使用最新版本 --> </dependency>
-
Student实体类
public class Student{ private String name;//姓名 //无参的构造 public Student(){ } //构造方法 public Student(String name){ this.name = name; } //get and set public void setName(String name){ this.name = name; } public String getName(){ return this.name; } //toString @Override public String toString(){ return this.name; } }
-
从Excel文件创建学生名单
/** * 方法用于从Excel文件创建学生名单 * @param filePath 文件路径 * @return 学生列表 */ public static List<Student> readStudentListFromExcel(String filePath) { List<Student> students = new ArrayList<>(); try (FileInputStream fis = new FileInputStream(new File(filePath))) { //这里调用选择创建相应的工作簿对象的方法 //.xls 和 .xlsx 使用不同的对象进行读取 Workbook wb = createAppropriateWorkbook(fis, filePath); //拿到第一个表 Sheet sheet = wb.getSheetAt(0); //遍历每一行 for (Row row : sheet) { //循环遍历当前行的每一个单元格。 for (Cell cell : row) { //设置单元格的数据类型为字符串类型. cell.setCellType(CellType.STRING); //将学生的姓名封装为一个学生对象,并添加到学生列表中。 String name = cell.getStringCellValue(); students.add(new Student(name)); } } //关流 fis.close(); } catch (IOException e) { e.printStackTrace(); } //返回 return students; } /** * 根据文件路径来判断使用何种Workbook对象 *.xls 文件,创建 HSSFWorkbook 对象 *.xlsx 文件,创建 XSSFWorkbook 对象 * @param fis 文件输入流 * @param filePath 文件路径 * @return Workbook 对象 * @throws IOException 如果读取文件出现错误时抛出 IOException */ public static Workbook createAppropriateWorkbook(FileInputStream fis, String filePath) throws IOException { // 从文件路径中获取文件扩展名 String fileExtension = filePath.substring(filePath.lastIndexOf(".") + 1); Workbook wb = null; // 根据文件扩展名选择创建相应的工作簿对象 if (fileExtension.equals("xls")) { wb = new HSSFWorkbook(fis); } else if (fileExtension.equals("xlsx")) { wb = new XSSFWorkbook(fis); } return wb; }
-
根据学生集合随机生成座位
/** * 创建座位图 * @param rows 行数 * @param columns 列数 * @param students 学生列表 * @return 创建的座位图 */ public static Student[][] createSeatMap(int rows, int columns, List<Student> students) { // 创建指定行数和列数的二维学生数组 Student[][] seatMap = new Student[rows][columns]; // 创建随机数生成器 Random random = new Random(System.currentTimeMillis()); // 遍历座位图的每一行和每一列 for (int row = 0; row < seatMap.length; row++) { for (int column = 0; column < seatMap[row].length; column++) { // 生成一个随机索引,用于从学生列表中选择学生 int index = random.nextInt(students.size()); // 从学生列表中获取选中的学生,并将其添加到座位图中 seatMap[row][column] = students.get(index); // 从学生列表中移除已经分配座位的学生,以避免重复分配 students.remove(index); } } return seatMap; }
-
控制台打印方法
/** * 打印座位分布图 * @param seatMap 座位分布图 */ public static void printSeatMap(Student[][] seatMap) { System.out.print("\t\t"); for (int i = 0; i < seatMap[0].length; i++) { System.out.print("列" + (i + 1) + "\t"); } System.out.println("\n"); for (int i = 0; i < seatMap.length ; i++) { if (i+1 >= 10) { System.out.print("行" + (i + 1) + "\t"); }else { System.out.print("行" + (i + 1) + "\t\t"); } for (int j = 0; j < seatMap[i].length; j++) { if (seatMap[i][j] != null) { System.out.print(seatMap[i][j] + "\t"); } else { System.out.print("\t"); } } System.out.println(); } }
-
将排座结果导出为 Excel 格式的文件。这个方法通过目录路径与文件名,创建一个新的Excel表格。
/** *导出座位分布图到指定目录的文件中 * @param seatMap 座位分布图数组 * @param directoryPath 目录路径 * @param fileName 文件名 */ public static void exportSeatMap(Student[][] seatMap,String directoryPath,String fileName) { //创建目录对象 File directory = new File(directoryPath); //如果目录不存在,测创建目录 if (!directory.exists()) { directory.mkdirs(); } //创建文件对象 File file = new File(fileName); try (FileOutputStream fos = new FileOutputStream(file)) { //如果文件已经存在,则删除文件 if (file.exists()) { file.delete(); file.createNewFile(); } // 创建工作簿 Workbook workbook = new XSSFWorkbook(); //创建表 Sheet sheet = workbook.createSheet(); // 遍历座位分布图数组,逐行写入工作表 for (int row = 0; row < seatMap.length; row++) { // 创建行 Row excelRow = sheet.createRow(row); // 遍历每行的座位,逐列写入工作表 for (int column = 0; column < seatMap[row].length; column++) { // 创建单元格 Cell excelCell = excelRow.createCell(column); // 设置单元格值为学生姓名 excelCell.setCellValue(seatMap[row][column].getName()); } } // 将工作簿写入输出流 workbook.write(fos); // 关闭输出流 fos.close(); System.out.println("座位分布表"+fileName+"已成功导出到,目录为:" + directoryPath + fileName); }catch (Exception e){ e.printStackTrace(); } }
-
对程序进行测试
-
创建一个excel存入数据。
-
上表模拟60名同学,10行6列进行随机分坐。
public static void main(String[] args) { String fileFile = "D:\\code\\codetest\\Student.xlsx"; int rows = 10; int columns = 6; List<Student> students = readStudentListFromExcel(fileFile); Student[][] seatMap = createSeatMap(rows, columns, students); //控制台展示 printSeatMap(seatMap); //打印一个空行 System.out.println(); //导出路径 String directoryPath = "D:\\code\\codetest\\"; //导出文件名 String fileName = "seatMap.xlsx"; //导出方法 exportSeatMap(seatMap,directoryPath,fileName); }
-
控制输出
- 创建的seatMap.xlsx表格
-
三、总结
这个小程序主要是通过使用Apache POI库来对Excel文件进行读写操作,同时也复习了io流、二维数组等知识点,并且和这个类同时具有一定实际意义,可以帮助学校或者培训机构随机生成座位。