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;">
|
||||
<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="downloadCSV()">导出</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,30 @@
|
||||
|
||||
|
||||
<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>
|
||||
|
||||
|
@ -15,10 +15,7 @@ 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.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@ -124,4 +121,30 @@ public class OutputController {
|
||||
}
|
||||
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;
|
||||
|
||||
import cyou.chenx221.helper.CsvHelper;
|
||||
import cyou.chenx221.helper.UsernameHelper;
|
||||
import cyou.chenx221.pojo.Course;
|
||||
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.RequestParam;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
@Controller
|
||||
@ -59,7 +61,7 @@ public class ScoreController {
|
||||
@RequestParam(value = "min", defaultValue = "-1", required = false) int min,//最低分
|
||||
@RequestParam(value = "max", defaultValue = "-1", required = false) int max,//最高分
|
||||
@RequestParam(value = "range_enabler", defaultValue = "false", required = false) boolean range_enabler,//是否启用分数范围
|
||||
Model model) {
|
||||
Model model) throws IOException {
|
||||
|
||||
//username helper start
|
||||
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);
|
||||
|
||||
scores = scoreService.getQueryScores(score);
|
||||
//TODO: query result download(csv)
|
||||
// courses = courseService.getQueryCourses(course);
|
||||
// model.addAttribute("score", score);
|
||||
String download = new CsvHelper().generateScoreCSVFile(scores);
|
||||
model.addAttribute("download", download);
|
||||
model.addAttribute("scores", scores);
|
||||
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="/score/**" access="hasRole('admin')"/>
|
||||
<security:intercept-url pattern="/output/**" access="hasRole('admin')"/>
|
||||
<security:intercept-url pattern="/system/**" 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="downloadCSV()">导出</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,30 @@
|
||||
|
||||
|
||||
<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>
|
||||
|
||||
|
Reference in New Issue
Block a user