一、项目简介
- 我负责任务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.绘制学生成绩分布柱状图
关键代码
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;
}