new function: output csv file
Signed-off-by: Chenx221 <chenx221@yandex.com>
This commit is contained in:
parent
885e2651ed
commit
f5a85585d2
@ -46,6 +46,8 @@
|
||||
<element id="library" level="project" name="Maven: org.springframework:spring-web:5.3.27" />
|
||||
<element id="library" level="project" name="Maven: org.springframework:spring-webmvc:5.3.27" />
|
||||
<element id="library" level="project" name="Maven: taglibs:standard:1.1.2" />
|
||||
<element id="library" level="project" name="Maven: org.apache.commons:commons-csv:1.10.0" />
|
||||
<element id="library" level="project" name="Maven: commons-io:commons-io:2.12.0" />
|
||||
</element>
|
||||
</element>
|
||||
</root>
|
||||
|
Binary file not shown.
@ -23,6 +23,8 @@
|
||||
<security:intercept-url pattern="/dashboard" access="hasRole('admin')"/>
|
||||
<security:intercept-url pattern="/student/**" access="hasRole('admin')"/>
|
||||
<security:intercept-url pattern="/course/**" access="hasRole('admin')"/>
|
||||
<security:intercept-url pattern="/score/**" access="hasRole('admin')"/>
|
||||
<security:intercept-url pattern="/output/**" access="hasRole('admin')"/>
|
||||
<!-- 未登录状态下会自动跳转到/login登录页-->
|
||||
<security:form-login login-page="/login"
|
||||
default-target-url="/dashboard"
|
||||
|
Binary file not shown.
Binary file not shown.
@ -130,7 +130,19 @@
|
||||
style="background-image: url('${pageContext.request.contextPath}/resources/img/jason-blackeye-nyL-rzwP-Mk-unsplash.jpg'); margin-top: -58.59px;">
|
||||
<div class="mask d-flex align-items-center h-100" style="background-color: hsla(0, 0%, 100%, 0.5);">
|
||||
<div class="container d-flex justify-content-center">
|
||||
<button type="button" class="btn btn-primary" onclick="location.href='../dashboard'">返回</button>
|
||||
<div>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<button type="button" class="btn btn-primary" onclick="location.href='../dashboard'">返回
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<button type="button" class="btn btn-primary" onclick="exportCSV()">导出</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-container rounded-4 shadow-3-strong"
|
||||
style="background-color: rgba(255,255,255,0.9); overflow-y: auto; max-height: 400px;">
|
||||
<table class="table table-striped table-hover border-primary">
|
||||
@ -166,7 +178,18 @@
|
||||
|
||||
|
||||
<script type="text/javascript" src="${pageContext.request.contextPath}/resources/js/mdb.min.js"></script>
|
||||
|
||||
<script>
|
||||
function exportCSV() {
|
||||
// 构造请求 URL,根据需要导出的类型传递参数
|
||||
var exportUrl = '/output/export-csv?type=course'; // 示例:导出学生数据
|
||||
var link = document.createElement('a');
|
||||
link.href = exportUrl;
|
||||
link.style.display = 'none';
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
|
@ -130,7 +130,20 @@
|
||||
style="background-image: url('${pageContext.request.contextPath}/resources/img/jason-blackeye-nyL-rzwP-Mk-unsplash.jpg'); margin-top: -58.59px;">
|
||||
<div class="mask d-flex align-items-center h-100" style="background-color: hsla(0, 0%, 100%, 0.5);">
|
||||
<div class="container d-flex justify-content-center">
|
||||
<button type="button" class="btn btn-primary" onclick="location.href='../dashboard'">返回</button>
|
||||
<div>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<button type="button" class="btn btn-primary" onclick="location.href='../dashboard'">返回
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<button type="button" class="btn btn-primary" onclick="exportCSV()">导出</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="table-container rounded-4 shadow-3-strong"
|
||||
style="background-color: rgba(255,255,255,0.9); overflow-y: auto; max-height: 400px;">
|
||||
<table class="table table-striped table-hover border-primary">
|
||||
@ -138,6 +151,8 @@
|
||||
<tr>
|
||||
<th scope="col">成绩ID</th>
|
||||
<th scope="col">学号</th>
|
||||
<th scope="col">学生姓名</th>
|
||||
<th scope="col">课程ID</th>
|
||||
<th scope="col">课程名</th>
|
||||
<th scope="col">成绩</th>
|
||||
</tr>
|
||||
@ -147,6 +162,8 @@
|
||||
<tr>
|
||||
<td>${score.scoreID}</td>
|
||||
<td>${score.student.id}</td>
|
||||
<td>${score.student.name}</td>
|
||||
<td>${score.course.courseID}</td>
|
||||
<td>${score.course.courseName}</td>
|
||||
<td>${score.score}</td>
|
||||
</tr>
|
||||
@ -168,7 +185,18 @@
|
||||
|
||||
|
||||
<script type="text/javascript" src="${pageContext.request.contextPath}/resources/js/mdb.min.js"></script>
|
||||
|
||||
<script>
|
||||
function exportCSV() {
|
||||
// 构造请求 URL,根据需要导出的类型传递参数
|
||||
var exportUrl = '/output/export-csv?type=score'; // 示例:导出学生数据
|
||||
var link = document.createElement('a');
|
||||
link.href = exportUrl;
|
||||
link.style.display = 'none';
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
|
@ -130,7 +130,19 @@
|
||||
style="background-image: url('${pageContext.request.contextPath}/resources/img/jason-blackeye-nyL-rzwP-Mk-unsplash.jpg'); margin-top: -58.59px;">
|
||||
<div class="mask d-flex align-items-center h-100" style="background-color: hsla(0, 0%, 100%, 0.5);">
|
||||
<div class="container d-flex justify-content-center">
|
||||
<button type="button" class="btn btn-primary" onclick="location.href='../dashboard'">返回</button>
|
||||
<div>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<button type="button" class="btn btn-primary" onclick="location.href='../dashboard'">返回
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<button type="button" class="btn btn-primary" onclick="exportCSV()">导出</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-container rounded-4 shadow-3-strong"
|
||||
style="background-color: rgba(255,255,255,0.9); overflow-y: auto; max-height: 400px;">
|
||||
<table class="table table-striped table-hover border-primary">
|
||||
@ -172,7 +184,18 @@
|
||||
|
||||
|
||||
<script type="text/javascript" src="${pageContext.request.contextPath}/resources/js/mdb.min.js"></script>
|
||||
|
||||
<script>
|
||||
function exportCSV() {
|
||||
// 构造请求 URL,根据需要导出的类型传递参数
|
||||
var exportUrl = '/output/export-csv?type=student'; // 示例:导出学生数据
|
||||
var link = document.createElement('a');
|
||||
link.href = exportUrl;
|
||||
link.style.display = 'none';
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
|
@ -156,5 +156,15 @@
|
||||
<artifactId>log4j-core</artifactId>
|
||||
<version>2.12.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-csv</artifactId>
|
||||
<version>1.10.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>2.12.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -0,0 +1,127 @@
|
||||
package cyou.chenx221.controller;
|
||||
|
||||
import cyou.chenx221.pojo.Course;
|
||||
import cyou.chenx221.pojo.Score;
|
||||
import cyou.chenx221.pojo.Student;
|
||||
import cyou.chenx221.service.CourseService;
|
||||
import cyou.chenx221.service.ScoreService;
|
||||
import cyou.chenx221.service.StudentService;
|
||||
import org.apache.commons.csv.CSVFormat;
|
||||
import org.apache.commons.csv.CSVPrinter;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.PrintWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/output")
|
||||
public class OutputController {
|
||||
|
||||
@Autowired
|
||||
private StudentService studentService;
|
||||
|
||||
@Autowired
|
||||
private CourseService courseService;
|
||||
|
||||
@Autowired
|
||||
private ScoreService scoreService;
|
||||
|
||||
@GetMapping("/export-csv")
|
||||
public void exportCSV(HttpServletResponse response, @RequestParam("type") String type) throws IOException {
|
||||
response.setHeader("Content-Disposition", "attachment; filename=export.csv");
|
||||
response.setContentType("text/csv; charset=UTF-8"); // 设置字符编码为UTF-8
|
||||
response.setCharacterEncoding("UTF-8"); // 设置响应字符编码为UTF-8
|
||||
|
||||
List<String> headers;
|
||||
List<List<String>> data;
|
||||
|
||||
switch (type) {
|
||||
case "student" -> {
|
||||
headers = Arrays.asList("学生ID", "学生姓名", "性别", "出生日期", "联系方式", "班级");
|
||||
List<Student> students = studentService.getAllStudents(); // 根据实际情况获取学生数据
|
||||
data = transformStudentsToData(students);
|
||||
}
|
||||
case "course" -> {
|
||||
headers = Arrays.asList("课程ID", "课程名", "课程描述");
|
||||
List<Course> courses = courseService.getAllCourses(); // 根据实际情况获取课程数据
|
||||
data = transformCoursesToData(courses);
|
||||
}
|
||||
case "score" -> {
|
||||
headers = Arrays.asList("成绩ID", "学生ID", "学生姓名", "课程ID", "课程名称", "成绩");
|
||||
List<Score> scores = scoreService.getAllScores(); // 根据实际情况获取成绩数据
|
||||
data = transformScoresToData(scores);
|
||||
}
|
||||
default -> throw new IllegalArgumentException("Invalid export type: " + type);
|
||||
}
|
||||
|
||||
// 使用 Apache Commons CSV 构建 CSV 输出
|
||||
try (OutputStream outputStream = response.getOutputStream();
|
||||
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8);
|
||||
CSVPrinter csvPrinter = new CSVPrinter(outputStreamWriter, CSVFormat.DEFAULT)) {
|
||||
csvPrinter.printRecord(headers);
|
||||
for (List<String> row : data) {
|
||||
csvPrinter.printRecord(row);
|
||||
}
|
||||
csvPrinter.flush();
|
||||
}
|
||||
}
|
||||
|
||||
// 辅助方法:将学生对象列表转换为数据列表
|
||||
private List<List<String>> transformStudentsToData(List<Student> students) {
|
||||
List<List<String>> data = new ArrayList<>();
|
||||
for (Student student : students) {
|
||||
List<String> rowData = Arrays.asList(
|
||||
String.valueOf(student.getId()),
|
||||
student.getName(),
|
||||
student.getSex(),
|
||||
student.getBirthday().toString(),
|
||||
String.valueOf(student.getPhone()),
|
||||
String.valueOf(student.getClasses())
|
||||
);
|
||||
data.add(rowData);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
// 辅助方法:将课程对象列表转换为数据列表
|
||||
private List<List<String>> transformCoursesToData(List<Course> courses) {
|
||||
List<List<String>> data = new ArrayList<>();
|
||||
for (Course course : courses) {
|
||||
List<String> rowData = Arrays.asList(
|
||||
String.valueOf(course.getCourseID()),
|
||||
course.getCourseName(),
|
||||
course.getDescription()
|
||||
);
|
||||
data.add(rowData);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
// 辅助方法:将成绩对象列表转换为数据列表
|
||||
private List<List<String>> transformScoresToData(List<Score> scores) {
|
||||
List<List<String>> data = new ArrayList<>();
|
||||
for (Score score : scores) {
|
||||
List<String> rowData = Arrays.asList(
|
||||
String.valueOf(score.getScoreID()),
|
||||
String.valueOf(score.getStudent().getId()),
|
||||
score.getStudent().getName(),
|
||||
String.valueOf(score.getCourse().getCourseID()),
|
||||
score.getCourse().getCourseName(),
|
||||
String.valueOf(score.getScore())
|
||||
);
|
||||
data.add(rowData);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
@ -23,6 +23,8 @@
|
||||
<security:intercept-url pattern="/dashboard" access="hasRole('admin')"/>
|
||||
<security:intercept-url pattern="/student/**" access="hasRole('admin')"/>
|
||||
<security:intercept-url pattern="/course/**" access="hasRole('admin')"/>
|
||||
<security:intercept-url pattern="/score/**" access="hasRole('admin')"/>
|
||||
<security:intercept-url pattern="/output/**" access="hasRole('admin')"/>
|
||||
<!-- 未登录状态下会自动跳转到/login登录页-->
|
||||
<security:form-login login-page="/login"
|
||||
default-target-url="/dashboard"
|
||||
|
@ -130,7 +130,19 @@
|
||||
style="background-image: url('${pageContext.request.contextPath}/resources/img/jason-blackeye-nyL-rzwP-Mk-unsplash.jpg'); margin-top: -58.59px;">
|
||||
<div class="mask d-flex align-items-center h-100" style="background-color: hsla(0, 0%, 100%, 0.5);">
|
||||
<div class="container d-flex justify-content-center">
|
||||
<button type="button" class="btn btn-primary" onclick="location.href='../dashboard'">返回</button>
|
||||
<div>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<button type="button" class="btn btn-primary" onclick="location.href='../dashboard'">返回
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<button type="button" class="btn btn-primary" onclick="exportCSV()">导出</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-container rounded-4 shadow-3-strong"
|
||||
style="background-color: rgba(255,255,255,0.9); overflow-y: auto; max-height: 400px;">
|
||||
<table class="table table-striped table-hover border-primary">
|
||||
@ -166,7 +178,18 @@
|
||||
|
||||
|
||||
<script type="text/javascript" src="${pageContext.request.contextPath}/resources/js/mdb.min.js"></script>
|
||||
|
||||
<script>
|
||||
function exportCSV() {
|
||||
// 构造请求 URL,根据需要导出的类型传递参数
|
||||
var exportUrl = '/output/export-csv?type=course'; // 示例:导出学生数据
|
||||
var link = document.createElement('a');
|
||||
link.href = exportUrl;
|
||||
link.style.display = 'none';
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
|
@ -130,7 +130,20 @@
|
||||
style="background-image: url('${pageContext.request.contextPath}/resources/img/jason-blackeye-nyL-rzwP-Mk-unsplash.jpg'); margin-top: -58.59px;">
|
||||
<div class="mask d-flex align-items-center h-100" style="background-color: hsla(0, 0%, 100%, 0.5);">
|
||||
<div class="container d-flex justify-content-center">
|
||||
<button type="button" class="btn btn-primary" onclick="location.href='../dashboard'">返回</button>
|
||||
<div>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<button type="button" class="btn btn-primary" onclick="location.href='../dashboard'">返回
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<button type="button" class="btn btn-primary" onclick="exportCSV()">导出</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="table-container rounded-4 shadow-3-strong"
|
||||
style="background-color: rgba(255,255,255,0.9); overflow-y: auto; max-height: 400px;">
|
||||
<table class="table table-striped table-hover border-primary">
|
||||
@ -138,6 +151,8 @@
|
||||
<tr>
|
||||
<th scope="col">成绩ID</th>
|
||||
<th scope="col">学号</th>
|
||||
<th scope="col">学生姓名</th>
|
||||
<th scope="col">课程ID</th>
|
||||
<th scope="col">课程名</th>
|
||||
<th scope="col">成绩</th>
|
||||
</tr>
|
||||
@ -147,6 +162,8 @@
|
||||
<tr>
|
||||
<td>${score.scoreID}</td>
|
||||
<td>${score.student.id}</td>
|
||||
<td>${score.student.name}</td>
|
||||
<td>${score.course.courseID}</td>
|
||||
<td>${score.course.courseName}</td>
|
||||
<td>${score.score}</td>
|
||||
</tr>
|
||||
@ -168,7 +185,18 @@
|
||||
|
||||
|
||||
<script type="text/javascript" src="${pageContext.request.contextPath}/resources/js/mdb.min.js"></script>
|
||||
|
||||
<script>
|
||||
function exportCSV() {
|
||||
// 构造请求 URL,根据需要导出的类型传递参数
|
||||
var exportUrl = '/output/export-csv?type=score'; // 示例:导出学生数据
|
||||
var link = document.createElement('a');
|
||||
link.href = exportUrl;
|
||||
link.style.display = 'none';
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
|
@ -130,7 +130,19 @@
|
||||
style="background-image: url('${pageContext.request.contextPath}/resources/img/jason-blackeye-nyL-rzwP-Mk-unsplash.jpg'); margin-top: -58.59px;">
|
||||
<div class="mask d-flex align-items-center h-100" style="background-color: hsla(0, 0%, 100%, 0.5);">
|
||||
<div class="container d-flex justify-content-center">
|
||||
<button type="button" class="btn btn-primary" onclick="location.href='../dashboard'">返回</button>
|
||||
<div>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<button type="button" class="btn btn-primary" onclick="location.href='../dashboard'">返回
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<button type="button" class="btn btn-primary" onclick="exportCSV()">导出</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-container rounded-4 shadow-3-strong"
|
||||
style="background-color: rgba(255,255,255,0.9); overflow-y: auto; max-height: 400px;">
|
||||
<table class="table table-striped table-hover border-primary">
|
||||
@ -172,7 +184,18 @@
|
||||
|
||||
|
||||
<script type="text/javascript" src="${pageContext.request.contextPath}/resources/js/mdb.min.js"></script>
|
||||
|
||||
<script>
|
||||
function exportCSV() {
|
||||
// 构造请求 URL,根据需要导出的类型传递参数
|
||||
var exportUrl = '/output/export-csv?type=student'; // 示例:导出学生数据
|
||||
var link = document.createElement('a');
|
||||
link.href = exportUrl;
|
||||
link.style.display = 'none';
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
|
Reference in New Issue
Block a user