QueryResult Download as csv

Signed-off-by: Chenx221 <chenx221@yandex.com>
This commit is contained in:
Chenx221 2023-06-13 12:34:26 +08:00
parent eb0e715540
commit 83735978db
12 changed files with 247 additions and 10 deletions

BIN
project2/file-folder.lnk Normal file

Binary file not shown.

View File

@ -130,7 +130,19 @@
style="background-image: url('${pageContext.request.contextPath}/resources/img/jason-blackeye-nyL-rzwP-Mk-unsplash.jpg'); margin-top: -58.59px;"> 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="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"> <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="downloadCSV()">导出</button>
</div>
</div>
</div>
<div class="table-container rounded-4 shadow-3-strong" <div class="table-container rounded-4 shadow-3-strong"
style="background-color: rgba(255,255,255,0.9); overflow-y: auto; max-height: 400px;"> style="background-color: rgba(255,255,255,0.9); overflow-y: auto; max-height: 400px;">
<table class="table table-striped table-hover border-primary"> <table class="table table-striped table-hover border-primary">
@ -172,7 +184,30 @@
<script type="text/javascript" src="${pageContext.request.contextPath}/resources/js/mdb.min.js"></script> <script type="text/javascript" src="${pageContext.request.contextPath}/resources/js/mdb.min.js"></script>
<script>
function downloadCSV() {
// 获取文件名
var fileName = "${download}";
// 构建文件下载链接
var downloadLink = "/output/get-csv?filename=" + fileName;
// 创建一个隐藏的<a>元素并设置下载链接
var linkElement = document.createElement('a');
linkElement.href = downloadLink;
linkElement.target = "_blank";
linkElement.download = fileName;
// 将<a>元素添加到DOM树中
document.body.appendChild(linkElement);
// 模拟点击<a>元素来触发下载操作
linkElement.click();
// 从DOM树中移除<a>元素
document.body.removeChild(linkElement);
}
</script>
</body> </body>

View File

@ -15,10 +15,7 @@ import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.IOException; import java.io.*;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -124,4 +121,30 @@ public class OutputController {
} }
return data; return data;
} }
@GetMapping("/get-csv")
public void getCSV(HttpServletResponse response, @RequestParam("filename") String filename) throws IOException {
String filePath = "file" + File.separator + filename;
File file = new File(filePath);
if (file.exists()) {
// 设置响应头
response.setHeader("Content-Disposition", "attachment; filename=" + file.getName());
response.setContentType("text/csv");
// 读取文件内容并写入响应流
try (InputStream inputStream = new FileInputStream(file);
OutputStream outputStream = response.getOutputStream()) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
} catch (IOException e) {
// 处理异常
}
} else {
System.out.println("异常");
}
}
} }

View File

@ -1,5 +1,6 @@
package cyou.chenx221.controller; package cyou.chenx221.controller;
import cyou.chenx221.helper.CsvHelper;
import cyou.chenx221.helper.UsernameHelper; import cyou.chenx221.helper.UsernameHelper;
import cyou.chenx221.pojo.Course; import cyou.chenx221.pojo.Course;
import cyou.chenx221.pojo.Score; import cyou.chenx221.pojo.Score;
@ -13,6 +14,7 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import java.io.IOException;
import java.util.List; import java.util.List;
@Controller @Controller
@ -59,7 +61,7 @@ public class ScoreController {
@RequestParam(value = "min", defaultValue = "-1", required = false) int min,//最低分 @RequestParam(value = "min", defaultValue = "-1", required = false) int min,//最低分
@RequestParam(value = "max", defaultValue = "-1", required = false) int max,//最高分 @RequestParam(value = "max", defaultValue = "-1", required = false) int max,//最高分
@RequestParam(value = "range_enabler", defaultValue = "false", required = false) boolean range_enabler,//是否启用分数范围 @RequestParam(value = "range_enabler", defaultValue = "false", required = false) boolean range_enabler,//是否启用分数范围
Model model) { Model model) throws IOException {
//username helper start //username helper start
String username = new UsernameHelper().getCurrentUsername(); String username = new UsernameHelper().getCurrentUsername();
@ -86,9 +88,8 @@ public class ScoreController {
score = new Score((score_id == -1 ? null : score_id), ((student_id == -1 && name == null) ? null : (new Student((student_id == -1 ? null : student_id), name))), (course_id == -1 && course_name == null) ? null : (new Course((course_id == -1 ? null : course_id), course_name)), range_enabler ? (min == -1 ? null : min) : null, range_enabler ? (max == -1 ? null : max) : null); score = new Score((score_id == -1 ? null : score_id), ((student_id == -1 && name == null) ? null : (new Student((student_id == -1 ? null : student_id), name))), (course_id == -1 && course_name == null) ? null : (new Course((course_id == -1 ? null : course_id), course_name)), range_enabler ? (min == -1 ? null : min) : null, range_enabler ? (max == -1 ? null : max) : null);
scores = scoreService.getQueryScores(score); scores = scoreService.getQueryScores(score);
//TODO: query result download(csv) String download = new CsvHelper().generateScoreCSVFile(scores);
// courses = courseService.getQueryCourses(course); model.addAttribute("download", download);
// model.addAttribute("score", score);
model.addAttribute("scores", scores); model.addAttribute("scores", scores);
return "scoreQueryResult"; return "scoreQueryResult";
} }

View File

@ -0,0 +1,9 @@
package cyou.chenx221.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/system")
public class SystemController {
}

View File

@ -0,0 +1,133 @@
package cyou.chenx221.helper;
import cyou.chenx221.pojo.Course;
import cyou.chenx221.pojo.Score;
import cyou.chenx221.pojo.Student;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class CsvHelper {
public String generateScoreCSVFile(List<Score> scores) throws IOException {
List<String> headers;
headers = Arrays.asList("成绩ID", "学生ID", "学生姓名", "课程ID", "课程名称", "成绩");
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);
}
String directoryPath = "file";
File directory = new File(directoryPath);
if (!directory.exists()) {
boolean created = directory.mkdir(); //Be careful, path: tomcat's installation path (D:\softs\res\apache-tomcat-9.0.75-windows-x64\apache-tomcat-9.0.75\bin)
if (created) {
System.out.println("目录已创建");
} else {
System.out.println("无法创建目录");
}
}
File csvFile = new File("file/export-" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss")) + ".csv");
try (PrintWriter writer = new PrintWriter(csvFile);
CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT)) {
csvPrinter.printRecord(headers);
for (List<String> row : data) {
csvPrinter.printRecord(row);
}
csvPrinter.flush();
}
return csvFile.getName();
}
public String generateStudentCSVFile(List<Student> students) throws IOException {
List<String> headers;
headers = Arrays.asList("学生ID", "学生姓名", "性别", "出生日期", "联系方式", "班级");
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);
}
String directoryPath = "file";
File directory = new File(directoryPath);
if (!directory.exists()) {
boolean created = directory.mkdir(); //Be careful, path: tomcat's installation path (D:\softs\res\apache-tomcat-9.0.75-windows-x64\apache-tomcat-9.0.75\bin)
if (created) {
System.out.println("目录已创建");
} else {
System.out.println("无法创建目录");
}
}
File csvFile = new File("file/export-" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss")) + ".csv");
try (PrintWriter writer = new PrintWriter(csvFile);
CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT)) {
csvPrinter.printRecord(headers);
for (List<String> row : data) {
csvPrinter.printRecord(row);
}
csvPrinter.flush();
}
return csvFile.getName();
}
public String generateCourseCSVFile(List<Course> courses) throws IOException {
List<String> headers;
headers = Arrays.asList("课程ID", "课程名", "课程描述");
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);
}
String directoryPath = "file";
File directory = new File(directoryPath);
if (!directory.exists()) {
boolean created = directory.mkdir(); //Be careful, path: tomcat's installation path (D:\softs\res\apache-tomcat-9.0.75-windows-x64\apache-tomcat-9.0.75\bin)
if (created) {
System.out.println("目录已创建");
} else {
System.out.println("无法创建目录");
}
}
File csvFile = new File("file/export-" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss")) + ".csv");
try (PrintWriter writer = new PrintWriter(csvFile);
CSVPrinter csvPrinter = new CSVPrinter(writer, CSVFormat.DEFAULT)) {
csvPrinter.printRecord(headers);
for (List<String> row : data) {
csvPrinter.printRecord(row);
}
csvPrinter.flush();
}
return csvFile.getName();
}
}

View File

@ -25,6 +25,7 @@
<security:intercept-url pattern="/course/**" access="hasRole('admin')"/> <security:intercept-url pattern="/course/**" access="hasRole('admin')"/>
<security:intercept-url pattern="/score/**" access="hasRole('admin')"/> <security:intercept-url pattern="/score/**" access="hasRole('admin')"/>
<security:intercept-url pattern="/output/**" access="hasRole('admin')"/> <security:intercept-url pattern="/output/**" access="hasRole('admin')"/>
<security:intercept-url pattern="/system/**" access="hasRole('admin')"/>
<!-- 未登录状态下会自动跳转到/login登录页--> <!-- 未登录状态下会自动跳转到/login登录页-->
<security:form-login login-page="/login" <security:form-login login-page="/login"
default-target-url="/dashboard" default-target-url="/dashboard"

View File

@ -130,7 +130,19 @@
style="background-image: url('${pageContext.request.contextPath}/resources/img/jason-blackeye-nyL-rzwP-Mk-unsplash.jpg'); margin-top: -58.59px;"> 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="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"> <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="downloadCSV()">导出</button>
</div>
</div>
</div>
<div class="table-container rounded-4 shadow-3-strong" <div class="table-container rounded-4 shadow-3-strong"
style="background-color: rgba(255,255,255,0.9); overflow-y: auto; max-height: 400px;"> style="background-color: rgba(255,255,255,0.9); overflow-y: auto; max-height: 400px;">
<table class="table table-striped table-hover border-primary"> <table class="table table-striped table-hover border-primary">
@ -172,7 +184,30 @@
<script type="text/javascript" src="${pageContext.request.contextPath}/resources/js/mdb.min.js"></script> <script type="text/javascript" src="${pageContext.request.contextPath}/resources/js/mdb.min.js"></script>
<script>
function downloadCSV() {
// 获取文件名
var fileName = "${download}";
// 构建文件下载链接
var downloadLink = "/output/get-csv?filename=" + fileName;
// 创建一个隐藏的<a>元素并设置下载链接
var linkElement = document.createElement('a');
linkElement.href = downloadLink;
linkElement.target = "_blank";
linkElement.download = fileName;
// 将<a>元素添加到DOM树中
document.body.appendChild(linkElement);
// 模拟点击<a>元素来触发下载操作
linkElement.click();
// 从DOM树中移除<a>元素
document.body.removeChild(linkElement);
}
</script>
</body> </body>