当前位置: 首页 > news >正文

SpringBoot项目Excel模板下载功能详解

项目背景

"知分"系统是一款基于SpringBoot和Vue架构开发的B/S模式在线成绩管理平台,旨在解决传统成绩通知方式(如纸质成绩单、家长群通知)存在的效率低下、易出错、查询不便且不易保存等问题。

该系统作为连接家长与教师的数字化桥梁,具有以下核心价值:

  • 对于家长​:通过微信小程序即可随时随地、安全便捷地查询子女的最新考试成绩与排名,促进家校沟通
  • 对于教师/学校​:提供高效的Excel一键式成绩录入工具,自动完成分数统计与排名分析,通过可视化图表直观展示教学成果,极大减轻成绩管理工作负担

该系统实现了成绩管理的数字化、自动化与智能化,显著提升了家校互动的体验与效率。

本文将重点讲解成绩录入功能中Excel模板下载的实现细节。

功能展示

点击"录入成绩"按钮后会出现弹窗:

该功能支持上传xls和xlsx文件,并提供模板下载功能。模板会自动加载对应班级学生和考试名称,教师只需填写各科分数即可。

前端实现详解

1. 按钮触发逻辑

前端页面使用Element UI组件,点击"录入成绩"按钮触发相应事件:

<div class="card-actions"><el-button type="primary" size="small" @click="handleImportScore(classItem.id)"class="action-btn"><i class="el-icon-upload"></i>录入成绩</el-button><el-button type="default" size="small" @click="handleViewDetails(classItem.id)"class="action-btn"><i class="el-icon-view"></i>查看详情</el-button>
</div>

点击"录入成绩"按钮后,会触发handleImportScore方法并将班级ID作为参数传递:

// 处理导入成绩
handleImportScore(classId) {this.currentClassId = classIdthis.scoreDialogVisible = truethis.examName = ''this.fileList = []this.selectedFile = null
}

此方法主要完成以下工作:

  • 设置当前班级ID
  • 打开成绩录入弹窗
  • 重置相关表单数据

2. 模板下载功能

弹窗中的模板下载区域代码如下:

<div class="upload-tips"><el-button type="primary" size="small" @click="downloadExcelTemplate"class="download-template-btn"><i class="el-icon-download"></i>点击下载样本</el-button><p style="margin-top: 10px; color: #909399; font-size: 12px;">下载后填写分数,再上传即可</p>
</div>

点击下载按钮后,触发downloadExcelTemplate方法:

// 下载Excel模板
downloadExcelTemplate() {// 条件校验if (!this.currentClassId) {this.$message.error('未选择班级')return}if (!this.selectedExamId) {this.$message.warning('请先选择考试')return}try {// 显示加载提示this.$message({message: '正在生成模板,请稍候',type: 'info',duration: 0})// 获取班级和考试信息用于构建文件名const exam = this.homeData.exams.find(e => e.id === this.selectedExamId)const className = this.homeData.classes.find(c => c.id === this.currentClassId)?.name || '未知班级'const examName = exam?.name || '未知考试'// 设置token到请求头,防止被权限拦截const token = this.$store.state.user.tokenif (!token) {this.$message.warning('登录状态失效,请重新登录')setTimeout(() => {this.$router.push('/login')}, 1000)return}// 使用XHR方式下载文件,确保携带tokenconst xhr = new XMLHttpRequest()const requestUrl = `/teacher/home/downloadTemplate/${this.currentClassId}/${this.selectedExamId}`xhr.open('GET', requestUrl, true)xhr.setRequestHeader('Authorization', 'Bearer ' + token)xhr.responseType = 'blob'// 传递className和examName到回调函数中const downloadContext = {className: className,examName: examName,component: this}xhr.onload = function() {// 处理返回结果if (xhr.status === 200) {// 关闭所有消息提示downloadContext.component.$message.closeAll()downloadContext.component.$message.success('模板下载成功')try {// 设置文件名let finalFileName = `${downloadContext.className}成绩导入表${downloadContext.examName}.xlsx`const contentDisposition = xhr.getResponseHeader('Content-Disposition')// 根据响应类型设置正确的MIME类型let mimeType = 'application/octet-stream'const contentType = xhr.getResponseHeader('Content-Type')if (contentType) {mimeType = contentType}// 创建下载链接const blob = new Blob([xhr.response], { type: mimeType })const url = URL.createObjectURL(blob)// 创建a标签并模拟点击下载const downloadLink = document.createElement('a')downloadLink.href = urldownloadLink.setAttribute('download', finalFileName)downloadLink.style.display = 'none'document.body.appendChild(downloadLink)downloadLink.click()// 延迟移除,确保点击事件完成setTimeout(() => {document.body.removeChild(downloadLink)URL.revokeObjectURL(url)}, 100)} catch (downloadError) {console.error('下载文件处理失败:', downloadError)downloadContext.component.$message.error('文件下载处理失败')}} else {console.error('请求失败,状态码:', xhr.status)downloadContext.component.$message.closeAll()downloadContext.component.$message.error('生成模板失败:请稍后重试')}}xhr.onerror = function(e) {console.error('网络错误:', e)this.$message.closeAll()this.$message.error('生成模板失败:网络错误')}xhr.send()} catch (error) {console.error('生成模板失败:', error)this.$message.closeAll()this.$message.error('生成模板失败:' + (error.message || '请稍后重试'))}
}

该方法的关键实现点包括:

  1. 进行前置条件校验(班级和考试选择)
  2. 获取token并设置到请求头中
  3. 使用XMLHttpRequest发起请求,设置responseType为blob
  4. 处理响应并创建下载链接
  5. 添加异常处理机制,确保用户体验

后端实现详解

1. Controller层实现

后端使用SpringBoot框架,Controller层代码如下:

package com.eduscore.controller;import com.eduscore.domain.Student;
import com.eduscore.service.ITeacherHomeService;
import com.eduscore.common.core.controller.BaseController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;@RestController
@RequestMapping("/teacher/home")
public class TeacherHomeController extends BaseController {@Autowiredprivate ITeacherHomeService teacherHomeService;/​**​* 下载Excel成绩导入模板*/@GetMapping("/downloadTemplate/{classId}/{examId}")public void downloadExcelTemplate(@PathVariable Integer classId, @PathVariable Integer examId, HttpServletResponse response) {try {// 设置响应头response.setContentType("text/csv;charset=utf-8");response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("成绩导入模板.csv", "UTF-8"));// 获取班级学生列表List<Student> students = teacherHomeService.getClassStudents(classId);// 获取班级考试信息Map<String, Object> examInfo = teacherHomeService.getClassExamInfo(classId, examId);// 获取考试科目List<String> subjectNames = (List<String>) examInfo.get("subjectNames");// 生成CSV内容StringBuilder csvContent = new StringBuilder();// 添加标题行csvContent.append("学生姓名,班级");for (String subject : subjectNames) {csvContent.append(",").append(subject);}csvContent.append(",").append("考试名称");csvContent.append("\n");// 添加学生数据行String className = (String) examInfo.get("className");String examName = (String) examInfo.get("examName");for (Student student : students) {csvContent.append(student.getName()).append(",").append(className);// 为每个科目添加空成绩列for (int i = 0; i < subjectNames.size(); i++) {csvContent.append(",");}csvContent.append(",").append(examName);csvContent.append("\n");}// 输出CSV文件try (OutputStream out = response.getOutputStream()) {// 添加BOM头,确保Excel能正确识别UTF-8编码out.write(0xEF);out.write(0xBB);out.write(0xBF);out.write(csvContent.toString().getBytes(StandardCharsets.UTF_8));out.flush();}} catch (IOException e) {e.printStackTrace();}}
}

2. Service层实现

Service层负责业务逻辑处理:

package com.eduscore.service.impl;import com.eduscore.domain.*;
import com.eduscore.mapper.*;
import com.eduscore.service.ITeacherHomeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.HashMap;@Service
public class TeacherHomeServiceImpl implements ITeacherHomeService {@Autowiredprivate TeacherMapper teacherMapper;@Autowiredprivate SchoolMapper schoolMapper;@Autowiredprivate StudentMapper studentMapper;@Autowiredprivate ClassMapper classMapper;@Autowiredprivate ExamMapper examMapper;@Autowiredprivate ScoreMapper scoreMapper;@Autowiredprivate SubjectMapper subjectMapper;@Overridepublic Map<String, Object> getClassExamInfo(Integer classId, Integer examId) {// 获取班级信息Class clazz = classMapper.selectClassById(classId);// 获取考试信息Exam exam = examMapper.selectExamById(examId);// 获取该班级该考试的所有科目List<Subject> subjects = subjectMapper.selectSubjectList(new Subject());Map<String, Object> result = new HashMap<>();result.put("className", clazz != null ? clazz.getName() : "");result.put("examName", exam != null ? exam.getName() : "");List<String> subjectNames = subjects.stream().map(Subject::getName).collect(Collectors.toList());result.put("subjectNames", subjectNames);return result;}
}

实现原理总结

  1. 前端触发​:用户点击下载模板按钮,前端进行条件校验并携带认证信息发起请求
  2. 后端处理​:Controller接收请求,调用Service层获取班级、考试和科目信息
  3. 模板生成​:后端动态生成CSV格式的模板文件,包含学生列表和科目信息
  4. 文件返回​:设置正确的响应头和信息,将文件流返回给前端
  5. 前端下载​:前端接收文件流,创建下载链接并触发浏览器下载

生成的模板示例

通过以上实现,教师可以下载预先填充了班级学生信息和考试科目的模板,只需填写分数即可完成成绩录入,极大提高了工作效率。

下一篇文章将详细讲解成绩录入功能的实现细节,包括文件上传、数据解析和批量导入等关键技术点。

http://www.dtcms.com/a/415539.html

相关文章:

  • 搭建钓鱼网站教程互联网排名前十名的公司
  • 建立房产门户网站需要多少钱怎么修改网站备案信息
  • ​CentOS 7 安装 net-tools.rpm 包步骤详解(附 rpm 命令和 yum 方法)​附安装包
  • 品牌网站建设c重庆网站建设 客户同程
  • pci总线pci_dev的创建和匹配
  • 网站建设 百科自微网站首页
  • WebGoat - 刻意设计的不安全Web应用程序
  • 最新网站推广方法营销型网站的例子
  • 双绞线RLC参数对比与选型指南
  • 网站建设体会doc如何搭建一个网站
  • wordpress网站上传服务器如何优化网站
  • 快捷键已被占用怎么解决?解决快捷键冲突的方案。如何将一个快捷键映射为另一个快捷键?
  • 做网站 提要求辽宁住房和城乡建设厅网站首页
  • 网站keywords标签怎么写wordpress如何上传文档供下载
  • 管家婆网店ERP打印模板如何添加页码
  • Linux云服务器如何手动配置DNS?
  • 利用微博做网站排名福田蒙派克10座
  • php源码网站修改商业网站开发文档
  • 淘宝做网站 评价话语网站中的文章可以做排名吗
  • Ollama安装到D盘教程
  • 【金仓数据库产品体验官】KES-ORACLE兼容模式再体验之FLASHBACK
  • ReVanced Patches - Android应用功能增强补丁集
  • php制作网站用什么软件影视网站源码下载
  • Vala编程语言高级特性-参数方向
  • 网站开发有什么用图片编辑器免费
  • 通义万相Wan2.5模型实测,可生成音画同步视频
  • 电子商务网站开发费用调研报告网络营销方式思维导图
  • dll网站服务推荐电商网站建设
  • gRPC-Go - 高性能 gRPC 框架的 Go 实现
  • 将Gowin高云FPGA仿真库导入Modelsim中并编译