一、项目简介

  • 我负责任务5,6,8,也就是使用POI导入数据到Excel文件中、绘制学生成绩分布柱状图和随机生成10万条学生数据,此外还有设计GUI界面

二、系统功能结构图


三、个人任务介绍

1.GUI界面设计

登录注册界面


主菜单界面


添加学生界面


添加学生成绩界面


修改学生信息界面


学生学习情况报表界面


查找学生成绩界面


2.POI数据导入Excel文件

  • 通过下载相应的jar包,使用POI技术将数据导入Excel文件

关键代码

public static void inputToExcel(RankJframe rankJframe) throws IOException, RowsExceededException, WriteException {
		// 打开文件
		WritableWorkbook book = Workbook.createWorkbook(new File("students.xlsx"));
		// 生成名为“sheet1”的工作表,参数0表示这是第一页
		WritableSheet sheet1 = book.createSheet("sheet1", 0);
		SheetSettings ss = sheet1.getSettings();
		// 冻结第一行
		ss.setVerticalFreeze(1);
		for (int i = 0; i < COLUMN_NUMBERS; i++) {
			sheet1.setColumnView(i, 16);
		}

		// 设置字体格式,第一行字体加粗,其余字体不加粗
		WritableFont font = new WritableFont(WritableFont.createFont("宋体"), 14, WritableFont.BOLD);
		WritableFont font1 = new WritableFont(WritableFont.createFont("宋体"), 12, WritableFont.NO_BOLD);
		WritableCellFormat format = new WritableCellFormat(font);
		WritableCellFormat format1 = new WritableCellFormat(font1);
		// 把水平对齐方式指定为居中
		format.setAlignment(jxl.format.Alignment.CENTRE);
		format1.setAlignment(jxl.format.Alignment.CENTRE);
		// 把垂直对齐方式指定为居中
		format.setVerticalAlignment(jxl.format.VerticalAlignment.CENTRE);
		format1.setVerticalAlignment(jxl.format.VerticalAlignment.CENTRE);

		// 在Label对象的构造函数中指明单元格位置以及单元格内容,将定义好的单元格添加到工作表中
		sheet1.addCell(new Label(0, 0, "学号", format));
		sheet1.addCell(new Label(1, 0, "姓名", format));
		sheet1.addCell(new Label(2, 0, "Java成绩", format));
		sheet1.addCell(new Label(3, 0, "数学成绩", format));
		sheet1.addCell(new Label(4, 0, "体育成绩", format));
		sheet1.addCell(new Label(5, 0, "总成绩", format));
		sheet1.addCell(new Label(6, 0, "总成绩平均值", format));

		// 表格数据加入工作表sheet1中
		DefaultTableModel model = (DefaultTableModel) rankJframe.getjTable1().getModel();
		int count = model.getRowCount();
		// 数据导入到sheet1中
		if (count <= MAX_ROWS_NUMBER) {
			// 一行行地遍历表格
			for (int i = 0; i < count; i++) {
				// 一列列地遍历表格
				for (int j = 0; j < COLUMN_NUMBERS; j++) {
					String string = (String) model.getValueAt(i, j);
					// 从工作表sheet1的第二行开始添加数据
					sheet1.addCell(new Label(j, i + 1, string, format1));
				}
			}
		} else { // 数据导入到sheet2中
			WritableSheet sheet2 = book.createSheet("sheet2", 1);
			SheetSettings ss1 = sheet2.getSettings();
			// 冻结第一行
			ss1.setVerticalFreeze(1);
			// 工作表sheet2和sheet1的第一行内容相同
			sheet2.addCell(new Label(0, 0, "学号", format));
			sheet2.addCell(new Label(1, 0, "姓名", format));
			sheet2.addCell(new Label(2, 0, "Java成绩", format));
			sheet2.addCell(new Label(3, 0, "数学成绩", format));
			sheet2.addCell(new Label(4, 0, "体育成绩", format));
			sheet2.addCell(new Label(5, 0, "总成绩", format));
			sheet2.addCell(new Label(6, 0, "总成绩平均值", format));
			for (int i = 0; i < COLUMN_NUMBERS; i++) {
				sheet2.setColumnView(i, 16);
			}

			// 一行行地遍历表格
			for (int i = 0; i < MAX_ROWS_NUMBER; i++) {
				// 一列列地遍历表格
				for (int j = 0; j < COLUMN_NUMBERS; j++) {
					String string = (String) model.getValueAt(i, j);
					// 从工作表sheet1的第二行开始添加数据
					sheet1.addCell(new Label(j, i + 1, string, format1));
				}
			}
			// 表格中的其他数据加入工作表sheet2中,一行行地遍历表格
			for (int i = MAX_ROWS_NUMBER; i < count; i++) {
				// 一列列地遍历表格
				for (int j = 0; j < COLUMN_NUMBERS; j++) {
					String string = (String) model.getValueAt(i, j);
					// 从工作表sheet2的第二行开始添加数据
					sheet2.addCell(new Label(j, i - 65534, string, format1));
				}
			}
		}

		// 写入数据并关闭文件
		book.write();
		book.close();
	}

3.绘制学生成绩分布柱状图

  • 通过下载相应的jar包,绘制学生成绩分布柱状图

关键代码

public static void drawChart() {
		double[] numbers = DataUtil.createArrays();
		DefaultCategoryDataset dataset = new DefaultCategoryDataset();
		dataset.addValue(numbers[0], "Java", "[0,10)");
		dataset.addValue(numbers[1], "数学", "[0,10)");
		dataset.addValue(numbers[2], "体育", "[0,10)");
		dataset.addValue(numbers[3], "Java", "[10,20)");
		dataset.addValue(numbers[4], "数学", "[10,20)");
		dataset.addValue(numbers[5], "体育", "[10,20)");
		dataset.addValue(numbers[6], "Java", "[20,30)");
		dataset.addValue(numbers[7], "数学", "[20,30)");
		dataset.addValue(numbers[8], "体育", "[20,30)");
		dataset.addValue(numbers[9], "Java", "[30,40)");
		dataset.addValue(numbers[10], "数学", "[30,40)");
		dataset.addValue(numbers[11], "体育", "[30,40)");
		dataset.addValue(numbers[12], "Java", "[40,50)");
		dataset.addValue(numbers[13], "数学", "[40,50)");
		dataset.addValue(numbers[14], "体育", "[40,50)");
		dataset.addValue(numbers[15], "Java", "[50,60)");
		dataset.addValue(numbers[16], "数学", "[50,60)");
		dataset.addValue(numbers[17], "体育", "[50,60)");
		dataset.addValue(numbers[18], "Java", "[60,70)");
		dataset.addValue(numbers[19], "数学", "[60,70)");
		dataset.addValue(numbers[20], "体育", "[60,70)");
		dataset.addValue(numbers[21], "Java", "[70,80)");
		dataset.addValue(numbers[22], "数学", "[70,80)");
		dataset.addValue(numbers[23], "体育", "[70,80)");
		dataset.addValue(numbers[24], "Java", "[80,90)");
		dataset.addValue(numbers[25], "数学", "[80,90)");
		dataset.addValue(numbers[26], "体育", "[80,90)");
		dataset.addValue(numbers[27], "Java", "[90,100)");
		dataset.addValue(numbers[28], "数学", "[90,100)");
		dataset.addValue(numbers[29], "体育", "[90,100)");

		// 图表标题
		JFreeChart chart = ChartFactory.createBarChart("学生成绩分布柱状图",
				// 目录轴的显示标签
				"三科成绩分布",
				// 数值轴的显示标签
				"百分比(%)",
				// 数据集
				dataset,
				// 图表方向:水平、垂直
				PlotOrientation.VERTICAL,
				// 是否显示底部图例
				true,
				// 是否生成工具
				false,
				// 是否生成URL链接
				false);

		BarRenderer renderer = new BarRenderer();
		// 显示每个柱的数值,并修改该数值的字体属性
		renderer.setDefaultItemLabelGenerator(new StandardCategoryItemLabelGenerator());
		renderer.setDefaultItemLabelsVisible(true);
		// 设置每一组柱状体之间的间隔为0
		renderer.setItemMargin(0.0);

		// 获取图表区域对象
		CategoryPlot plot = chart.getCategoryPlot();
		plot.setRenderer(renderer);
		// 设置图的背景颜色
		plot.setBackgroundPaint(ChartColor.WHITE);
		// 设置图的边框
		plot.setOutlinePaint(ChartColor.white);

		// 水平底部列表
		CategoryAxis domainAxis = plot.getDomainAxis();
		// 水平底部标题
		domainAxis.setLabelFont(new Font("宋体", Font.BOLD, 14));
		// 垂直标题
		domainAxis.setTickLabelFont(new Font("宋体", Font.BOLD, 12));
		// 设置分类标签以45度倾斜
		domainAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_45);

		// 获取柱状
		ValueAxis rangeAxis = plot.getRangeAxis();
		rangeAxis.setLabelFont(new Font("宋体", Font.BOLD, 15));
		// 解决了底部汉字乱码问题
		chart.getLegend().setItemFont(new Font("宋体", Font.BOLD, 15));
		// 设置标题字体
		chart.getTitle().setFont(new Font("宋体", Font.BOLD, 20));
		NumberAxis axis = (NumberAxis) rangeAxis;
		// 1为一个间隔单位
		axis.setTickUnit(new NumberTickUnit(1));
		// 设置纵轴的最小值
		rangeAxis.setLowerBound(0);
		// 设置纵轴的最大值
		rangeAxis.setUpperBound(100);
		// 自动设置数据轴数据范围
		rangeAxis.setAutoRange(true);

		ChartFrame chartFrame = new ChartFrame("学生成绩分布柱状图", chart);
		chartFrame.setLocation(380, 150);
		chartFrame.setVisible(true);
	}

4.随机生成10万条学生数据

  • 重点是随机生成三科成绩,要求服从以80为中心的正态分布

关键代码

/**
	 * 随机生成数学成绩,以80分为中心成正态分布
	 * 
	 * @return
	 */
	public static Integer getMath() {
		Random random = new Random();
		int math = 0;
		while (true) {
			math = (int) (random.nextGaussian() * Math.sqrt(900) + 80);
			// 数学成绩位于[0,100)之间
			if (math >= 0 && math < 100) {
				break;
			}
		}
		return math;
	}

	/**
	 * 随机生成Java成绩,以80分为中心成正态分布
	 * 
	 * @return
	 */
	public static Integer getJava() {
		Random random = new Random();
		int java = 0;
		while (true) {
			java = (int) (random.nextGaussian() * Math.sqrt(900) + 80);
			// Java成绩位于[0,100)之间
			if (java >= 0 && java < 100) {
				break;
			}
		}

		return java;
	}

	/**
	 * 随机生成体育成绩,以80分为中心成正态分布
	 * 
	 * @return
	 */
	public static Integer getSports() {
		Random random = new Random();
		int sports = 0;
		while (true) {
			sports = (int) (random.nextGaussian() * Math.sqrt(900) + 80);
			// 体育成绩位于[0,100)之间
			if (sports >= 0 && sports < 100) {
				break;
			}
		}
		return sports;
	}