Added the option to export as CSV to student, classroom, course and calendar schedule views.

This commit is contained in:
haxala1r
2025-12-18 15:47:42 +03:00
parent e53754d2a8
commit 93ac7d55a6
8 changed files with 239 additions and 2 deletions

View File

@@ -745,4 +745,68 @@ public class ScheduleCalendarController {
"Could not update the exam assignment. The exam may be locked.");
}
}
/**
* Exports the schedule as a CSV grid (days × time slots).
*/
@FXML
private void onExportCSV() {
if (currentSchedule == null || currentConfig == null) {
showAlert(Alert.AlertType.WARNING, "No Schedule",
"Please generate a schedule first.");
return;
}
javafx.stage.FileChooser fileChooser = new javafx.stage.FileChooser();
fileChooser.setTitle("Export Schedule as CSV");
fileChooser.getExtensionFilters().add(
new javafx.stage.FileChooser.ExtensionFilter("CSV Files", "*.csv"));
fileChooser.setInitialFileName("schedule_calendar.csv");
java.io.File file = fileChooser.showSaveDialog(scheduleGrid.getScene().getWindow());
if (file == null)
return;
try (java.io.PrintWriter writer = new java.io.PrintWriter(file)) {
int numDays = currentConfig.getNumDays();
int slotsPerDay = currentConfig.getSlotsPerDay();
// Header row: Time Slot, Day 1, Day 2, ...
StringBuilder header = new StringBuilder("Time Slot");
for (int day = 0; day < numDays; day++) {
LocalDate date = currentConfig.getStartDate().plusDays(day);
header.append(",").append(date.toString());
}
writer.println(header);
// Data rows: one per time slot
for (int slot = 0; slot < slotsPerDay; slot++) {
StringBuilder row = new StringBuilder();
TimeSlot timeSlot = currentConfig.getTimeSlot(0, slot);
String slotLabel = timeSlot != null
? timeSlot.getStartTime() + "-" + timeSlot.getEndTime()
: "Slot " + (slot + 1);
row.append(slotLabel);
for (int day = 0; day < numDays; day++) {
row.append(",");
// Find exams at this day/slot
List<String> exams = new ArrayList<>();
for (ExamAssignment a : currentSchedule.getAssignments().values()) {
if (a.isAssigned() && a.getDay() == day && a.getTimeSlotIndex() == slot) {
exams.add(a.getCourseCode() + " (" + a.getClassroomId() + ")");
}
}
row.append("\"").append(String.join("; ", exams)).append("\"");
}
writer.println(row);
}
showAlert(Alert.AlertType.INFORMATION, "Export Complete",
"Schedule exported to:\n" + file.getAbsolutePath());
} catch (java.io.IOException e) {
showAlert(Alert.AlertType.ERROR, "Export Failed",
"Could not write file: " + e.getMessage());
}
}
}

View File

@@ -265,4 +265,62 @@ public class ScheduleClassroomController {
return slotIndex;
}
}
/**
* Exports the selected classroom's schedule as CSV.
*/
@FXML
private void onExportCSV() {
Classroom selected = classroomComboBox.getValue();
if (selected == null) {
showAlert(javafx.scene.control.Alert.AlertType.WARNING, "No Classroom",
"Please select a classroom first.");
return;
}
if (scheduleTable.getItems().isEmpty()) {
showAlert(javafx.scene.control.Alert.AlertType.WARNING, "No Data",
"No schedule data to export.");
return;
}
javafx.stage.FileChooser fileChooser = new javafx.stage.FileChooser();
fileChooser.setTitle("Export Classroom Schedule as CSV");
fileChooser.getExtensionFilters().add(
new javafx.stage.FileChooser.ExtensionFilter("CSV Files", "*.csv"));
fileChooser.setInitialFileName("schedule_classroom_" + selected.getClassroomId() + ".csv");
java.io.File file = fileChooser.showSaveDialog(scheduleTable.getScene().getWindow());
if (file == null)
return;
try (java.io.PrintWriter writer = new java.io.PrintWriter(file)) {
// Header
writer.println("Classroom,Date,Time,Course,Students");
// Data rows
for (ClassroomSlotEntry entry : scheduleTable.getItems()) {
writer.println(String.format("%s,\"%s\",%s,%s,%d",
selected.getClassroomId(),
entry.getDate(),
entry.getTime(),
entry.getCourse(),
entry.getStudentCount()));
}
showAlert(javafx.scene.control.Alert.AlertType.INFORMATION, "Export Complete",
"Classroom schedule exported to:\n" + file.getAbsolutePath());
} catch (java.io.IOException e) {
showAlert(javafx.scene.control.Alert.AlertType.ERROR, "Export Failed",
"Could not write file: " + e.getMessage());
}
}
private void showAlert(javafx.scene.control.Alert.AlertType type, String title, String message) {
javafx.scene.control.Alert alert = new javafx.scene.control.Alert(type);
alert.setTitle(title);
alert.setHeaderText(null);
alert.setContentText(message);
alert.showAndWait();
}
}

View File

@@ -236,4 +236,55 @@ public class ScheduleCourseController {
return slotIndex;
}
}
/**
* Exports the course schedule as a CSV file.
*/
@FXML
private void onExportCSV() {
if (courseScheduleTable.getItems().isEmpty()) {
showAlert(javafx.scene.control.Alert.AlertType.WARNING, "No Data",
"No schedule data to export.");
return;
}
javafx.stage.FileChooser fileChooser = new javafx.stage.FileChooser();
fileChooser.setTitle("Export Course Schedule as CSV");
fileChooser.getExtensionFilters().add(
new javafx.stage.FileChooser.ExtensionFilter("CSV Files", "*.csv"));
fileChooser.setInitialFileName("schedule_courses.csv");
java.io.File file = fileChooser.showSaveDialog(courseScheduleTable.getScene().getWindow());
if (file == null)
return;
try (java.io.PrintWriter writer = new java.io.PrintWriter(file)) {
// Header
writer.println("Course Code,Date,Time,Classroom,Enrolled Students");
// Data rows
for (CourseScheduleEntry entry : courseScheduleTable.getItems()) {
writer.println(String.format("%s,\"%s\",%s,%s,%d",
entry.getCourseCode(),
entry.getDate(),
entry.getTime(),
entry.getClassroom(),
entry.getEnrolledCount()));
}
showAlert(javafx.scene.control.Alert.AlertType.INFORMATION, "Export Complete",
"Course schedule exported to:\n" + file.getAbsolutePath());
} catch (java.io.IOException e) {
showAlert(javafx.scene.control.Alert.AlertType.ERROR, "Export Failed",
"Could not write file: " + e.getMessage());
}
}
private void showAlert(javafx.scene.control.Alert.AlertType type, String title, String message) {
javafx.scene.control.Alert alert = new javafx.scene.control.Alert(type);
alert.setTitle(title);
alert.setHeaderText(null);
alert.setContentText(message);
alert.showAndWait();
}
}

View File

@@ -230,4 +230,62 @@ public class ScheduleStudentController {
return slotIndex;
}
}
/**
* Exports the selected student's schedule as CSV.
*/
@FXML
private void onExportCSV() {
Student selected = studentComboBox.getValue();
if (selected == null) {
showAlert(Alert.AlertType.WARNING, "No Student",
"Please select a student first.");
return;
}
if (scheduleTable.getItems().isEmpty()) {
showAlert(Alert.AlertType.WARNING, "No Data",
"No schedule data to export.");
return;
}
javafx.stage.FileChooser fileChooser = new javafx.stage.FileChooser();
fileChooser.setTitle("Export Student Schedule as CSV");
fileChooser.getExtensionFilters().add(
new javafx.stage.FileChooser.ExtensionFilter("CSV Files", "*.csv"));
fileChooser.setInitialFileName("schedule_student_" + selected.getStudentId() + ".csv");
java.io.File file = fileChooser.showSaveDialog(scheduleTable.getScene().getWindow());
if (file == null)
return;
try (java.io.PrintWriter writer = new java.io.PrintWriter(file)) {
// Header
writer.println("Student ID,Course,Date,Time,Classroom");
// Data rows
for (CourseScheduleEntry entry : scheduleTable.getItems()) {
writer.println(String.format("%s,%s,\"%s\",%s,%s",
selected.getStudentId(),
entry.getCourseCode(),
entry.getDateDisplay(),
entry.getTimeDisplay(),
entry.getClassroom()));
}
showAlert(Alert.AlertType.INFORMATION, "Export Complete",
"Student schedule exported to:\n" + file.getAbsolutePath());
} catch (java.io.IOException e) {
showAlert(Alert.AlertType.ERROR, "Export Failed",
"Could not write file: " + e.getMessage());
}
}
private void showAlert(Alert.AlertType type, String title, String message) {
Alert alert = new Alert(type);
alert.setTitle(title);
alert.setHeaderText(null);
alert.setContentText(message);
alert.showAndWait();
}
}

View File

@@ -123,7 +123,7 @@
<HBox spacing="12" alignment="CENTER_LEFT">
<Label text="📆 Generated Schedule" styleClass="subsection-title"/>
<Region HBox.hgrow="ALWAYS"/>
<Button text="📥 Export PDF" styleClass="small-button"/>
<Button fx:id="exportButton" text="📥 Export CSV" onAction="#onExportCSV" styleClass="small-button"/>
</HBox>
<!-- Schedule Grid -->

View File

@@ -19,6 +19,7 @@
<Label text="Select Classroom:"/>
<ComboBox fx:id="classroomComboBox" promptText="Choose a classroom..." prefWidth="200"/>
<Button text="Show Schedule" onAction="#onShowSchedule" styleClass="primary-button"/>
<Button text="📥 Export CSV" onAction="#onExportCSV"/>
</HBox>
</VBox>
</top>

View File

@@ -14,7 +14,11 @@
<padding>
<Insets top="20" right="20" bottom="20" left="20"/>
</padding>
<Label text="Course Schedule View" styleClass="section-title"/>
<HBox spacing="10" alignment="CENTER_LEFT">
<Label text="Course Schedule View" styleClass="section-title"/>
<Region HBox.hgrow="ALWAYS"/>
<Button text="📥 Export CSV" onAction="#onExportCSV"/>
</HBox>
<Label text="All courses and their exam assignments" wrapText="true"/>
<Separator/>
<TableView fx:id="courseScheduleTable" VBox.vgrow="ALWAYS">

View File

@@ -19,6 +19,7 @@
<Label text="Select Student:"/>
<ComboBox fx:id="studentComboBox" promptText="Choose a student..." prefWidth="200"/>
<Button text="Show Schedule" onAction="#onShowSchedule" styleClass="primary-button"/>
<Button text="📥 Export CSV" onAction="#onExportCSV"/>
</HBox>
</VBox>
</top>