QueryResult Download as csv
Signed-off-by: Chenx221 <chenx221@yandex.com>
This commit is contained in:
parent
eb0e715540
commit
83735978db
BIN
project2/file-folder.lnk
Normal file
BIN
project2/file-folder.lnk
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
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;">
|
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>
|
||||||
|
|
||||||
|
@ -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("异常");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -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";
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
}
|
133
project2/src/main/java/cyou/chenx221/helper/CsvHelper.java
Normal file
133
project2/src/main/java/cyou/chenx221/helper/CsvHelper.java
Normal 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();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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"
|
||||||
|
@ -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>
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user