跳至主要內容

学长敲代码原创大约 5 分钟教程C#学生信息管理系统学生成绩管理系统

接着我们进入第二阶段,上个阶段仅仅完成了学生信息管理系统,现在继续完成成绩部分

实现图
实现图

数据库创建

接着创建课程表和成绩表。

sqlserver

use student_manage;
-- 创建课程表
CREATE TABLE tb_course(
      cno VARCHAR(10), -- 课程号
      cname VARCHAR(30), -- 课程名
      teacher VARCHAR(100), -- 教师
      score INT, -- 学分
      PRIMARY KEY (cno)
);
GO
-- 插入课程数据
INSERT INTO tb_course VALUES('1001', '高数', '王老师', 5);
INSERT INTO tb_course VALUES('1002', '数据库原理', '李老师', 4);
GO
-- 创建成绩表
CREATE TABLE tb_score(
     sno VARCHAR(20), -- 学号
     cno VARCHAR(10), -- 课程号
     score INT, -- 分数
     PRIMARY KEY (cno, sno)
);
GO
-- 插入成绩数据
INSERT INTO tb_score VALUES('2024001', '1001', 50);
INSERT INTO tb_score VALUES('2024001', '1002', 85);
INSERT INTO tb_score VALUES('2024002', '1001', 68);
INSERT INTO tb_score VALUES('2024002', '1002', 89);
GO
-- 添加外键约束(学生-成绩)
ALTER TABLE tb_score ADD CONSTRAINT frn_stu_score
    FOREIGN KEY(sno) REFERENCES tb_student (sno);
GO
-- 添加外键约束(课程-成绩)
ALTER TABLE tb_score ADD CONSTRAINT frn_cou_score
    FOREIGN KEY(cno) REFERENCES tb_course (cno);
GO

mysql

create table tb_course(
	cno varchar(10), -- 课程号
	cname varchar(30), -- 课程名
	teacher varchar(100), -- 教师
	score int, -- 学分
    PRIMARY KEY (`cno`)
);
insert into tb_course values('1001','高数','王老师','5');
insert into tb_course values('1002','数据库原理','李老师','4');
create table tb_score(
	sno varchar(20), -- 学号
	cno varchar(10), -- 课程号
	score int, -- 分数
	PRIMARY KEY (`cno`,`sno`)
);
insert into tb_score values('2024001','1001','50');
insert into tb_score values('2024001','1002','85');
insert into tb_score values('2024002','1001','68');
insert into tb_score values('2024002','1002','89');

alter table tb_score add CONSTRAINT frn_stu_score
 FOREIGN KEY(sno) REFERENCES tb_student (sno);
alter table tb_score add CONSTRAINT frn_cou_score
 FOREIGN KEY(cno) REFERENCES tb_course (cno);

课程管理实现

参考学生管理增删改查实现

成绩管理实现

实现成绩的增删改查功能

导出excel

使用mysql需要下载mysql的驱动,下载NPOI.dll

using NPOI.SS.UserModel;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MyAutoApp
{
	class ExcelUtils
	{
        /// <summary>
        /// 导出到excel
        /// </summary>
        /// <param name="dgvUseName"></param>
        /// <param name="name"></param>
        public static void DataTableToExcel(DataGridView dgvUseName, string name)
        {
            if (dgvUseName.Rows.Count == 0)
            {
                MessageBox.Show("请您检查是否有数据导出", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            //提示用户保存文件位置
            SaveFileDialog saveFileDialog = new SaveFileDialog();
            //定义格式
            saveFileDialog.Filter = "Excel files (*.xls)|*.xls";
            //设置导出的sheet
            saveFileDialog.FilterIndex = 0;
            saveFileDialog.RestoreDirectory = true;
            saveFileDialog.CreatePrompt = true;
            //设置导出窗口的标题
            saveFileDialog.Title = "导出Excel文件到";
            //默认设置导出文件名称为空,让用户重新填写
            saveFileDialog.FileName = name;
            //显示导出框
            DialogResult result = DialogResult.Cancel;
            Thread t = new Thread((ThreadStart)(() => {
                result = saveFileDialog.ShowDialog();//获取点击取消保存excel文件的按钮事件
            }));
            t.SetApartmentState(ApartmentState.STA);
            t.Start();
            t.Join();
            if (result == DialogResult.Cancel) return;//点击取消
            //打开文件流 开始写入
            Stream myStream = saveFileDialog.OpenFile();
            StreamWriter sw = new StreamWriter(myStream, System.Text.Encoding.GetEncoding("gb2312"));
            string str = "";
            try
            {
                //写标题
                for (int i = 0; i < dgvUseName.ColumnCount; i++)
                {
                    if (i > 0)
                    {
                        str += "\t";
                    }
                    str += dgvUseName.Columns[i].HeaderText;
                }
                sw.WriteLine(str);
                //写内容
                for (int j = 0; j < dgvUseName.Rows.Count; j++)
                {
                    string tempStr = "";
                    for (int k = 0; k < dgvUseName.Columns.Count; k++)
                    {
                        if (k > 0)
                        {
                            tempStr += "\t";
                        }
                        if (dgvUseName.Rows[j].Cells[k].Value != null)
                        {
                            tempStr += dgvUseName.Rows[j].Cells[k].Value.ToString();
                        }
                        tempStr += "";
                    }
                    sw.WriteLine(tempStr);
                }
                MessageBox.Show("成功导出Excel表");
                sw.Close();
                myStream.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
            finally
            {
                sw.Close();
                myStream.Close();
            }
        }
    }
}

成绩统计查询图表

实现成绩统计查询(利用AI实现)

laodData()实现


            //统计

            // 检查是否选择了特定课程
            bool isSpecificCourseSelected = !string.IsNullOrEmpty(cno.SelectedValue?.ToString());

            // 统计数据结构
            DataTable statsTable = new DataTable();

            if (!isSpecificCourseSelected)
            {
                // 情况1:未选择具体课程 - 计算各科目及格率
                statsTable.Columns.Add("课程名");
                statsTable.Columns.Add("及格率", typeof(double));

                var courseGroups = dt.AsEnumerable()
                    .GroupBy(row => row.Field<string>("课程名"));

                foreach (var courseGroup in courseGroups)
                {
                    string courseName = courseGroup.Key;
                    int totalCount = courseGroup.Count();
                    int passCount = courseGroup.Count(row => {
                        object scoreObj = row["分数"];
                        double score = Convert.IsDBNull(scoreObj) ? 0 : Convert.ToDouble(scoreObj);
                        return score >= 60;
                    });

                    double passRate = totalCount > 0 ? Math.Round((passCount * 100.0) / totalCount, 2) : 0;
                    statsTable.Rows.Add(courseName, passRate);
                }
            }
            else
            {
                // 情况2:选择了具体课程 - 统计分数段人数
                statsTable.Columns.Add("分数段");
                statsTable.Columns.Add("人数", typeof(int));

                // 定义分数段
                var scoreRanges = new[] {
        new { Min = 0,  Max = 29,  Name = "0-29分" },
        new { Min = 30, Max = 49,  Name = "30-49分" },
        new { Min = 50, Max = 59,  Name = "50-59分" },
        new { Min = 60, Max = 69,  Name = "60-69分" },
        new { Min = 70, Max = 79,  Name = "70-79分" },
        new { Min = 80, Max = 89,  Name = "80-89分" },
        new { Min = 90, Max = 100, Name = "90-100分" }
    };

                // 初始化人数统计
                int[] counts = new int[scoreRanges.Length];

                // 统计每个分数段的人数
                foreach (DataRow row in dt.Rows)
                {
                    object scoreObj = row["分数"];
                    if (Convert.IsDBNull(scoreObj)) continue;

                    double score = Convert.ToDouble(scoreObj);
                    for (int i = 0; i < scoreRanges.Length; i++)
                    {
                        if (score >= scoreRanges[i].Min && score <= scoreRanges[i].Max)
                        {
                            counts[i]++;
                            break;
                        }
                    }
                }

                // 填充统计结果
                for (int i = 0; i < scoreRanges.Length; i++)
                {
                    statsTable.Rows.Add(scoreRanges[i].Name, counts[i]);
                }
            }

            // 配置Chart控件显示统计结果
            chart1.Series.Clear();
            chart1.Titles.Clear();

            // 添加主标题
            chart1.Titles.Add(isSpecificCourseSelected ?
                "课程成绩分布分析" : "各科目及格率统计");
            chart1.Titles[0].Font = new Font("微软雅黑", 12, FontStyle.Bold);

            // 创建数据系列
            Series series = new Series
            {
                Name = isSpecificCourseSelected ? "学生人数" : "及格率",
                ChartType = SeriesChartType.Column,
                IsValueShownAsLabel = true,
                Color = Color.SteelBlue
            };

            // 根据统计类型设置不同格式
            if (!isSpecificCourseSelected)
            {
                series.LabelFormat = "0.##'%'";
            }
            else
            {
                series.LabelFormat = "#人";
                // 添加数据点标签角度
                series["BarLabelStyle"] = "Center";
            }

            // 绑定数据
            foreach (DataRow row in statsTable.Rows)
            {
                string name = row.Field<string>(0);
                double value = Convert.ToDouble(row[1]);
                series.Points.AddXY(name, value);

                // 为及格率统计添加颜色区分
                if (!isSpecificCourseSelected && name.Contains("及格"))
                {
                    int pointIndex = series.Points.Count - 1;
                    series.Points[pointIndex].Color = value >= 60 ? Color.Green : Color.Orange;
                }
            }

            chart1.Series.Add(series);

            // 设置坐标轴样式
            chart1.ChartAreas[0].AxisX.Title = isSpecificCourseSelected ? "分数段" : "课程";
            chart1.ChartAreas[0].AxisY.Title = isSpecificCourseSelected ? "学生人数" : "及格率 (%)";

            if (!isSpecificCourseSelected)
            {
                // 及格率统计的设置
                chart1.ChartAreas[0].AxisY.Maximum = 100;
                chart1.ChartAreas[0].AxisY.Minimum = 0;
                chart1.ChartAreas[0].AxisY.Interval = 20;
            }

            // 使X轴标签倾斜45度避免重叠
            chart1.ChartAreas[0].AxisX.LabelStyle.Angle = -45;

            // 调整图例位置
            chart1.Legends.Clear();

感谢点赞、投币❤