動態圖表 -- eg1

問題:

前端vue,后端springboot,實現動態表格樣式,(表格List<Student>,Student類有年級,班級,文理科分類,姓名,學號,等屬性。先根據年級分類統計作為第一列,同個年級的合并,再根據文理科分類統計作為第二列,同樣分類的合并,最后根據班級分類統計,同個班級的合并行,第四列是學生學號,第五列是學生姓名。第一行是合并5列的學校名稱,第二行是合并3個格子的“分班信息”,合并2各格子的“學生信息”。學生信息的那2列要能讓前端點擊任一那兩列的格子時帶信息跳轉,跳轉信息包括(學生學號,年級,班級,文理科分類)。以上信息統一由后端返回給前端。表格列數固定,行數不固定,其中,合并行的合并行數或合并列的合并列數,會根據具體數據動態計算),提供完整的前后端代碼

動態表格實現(Vue + SpringBoot)

下面我將提供一個完整的解決方案,包括前端Vue和后端SpringBoot的實現。

后端SpringBoot實現

1. 實體類定義

 

java

// Student.java
public class Student {private String grade;       // 年級private String className;   // 班級private String subjectType; // 文理科分類private String name;        // 姓名private String studentId;   // 學號// 構造方法、getter和setterpublic Student() {}public Student(String grade, String className, String subjectType, String name, String studentId) {this.grade = grade;this.className = className;this.subjectType = subjectType;this.name = name;this.studentId = studentId;}// getter和setter方法// ...
}

2. 表格數據結構

 

java

// TableRow.java
public class TableRow {private String grade;          // 年級private String subjectType;    // 文理科分類private String className;      // 班級private String studentId;      // 學號private String studentName;    // 姓名private int gradeRowSpan;      // 年級合并行數private int subjectRowSpan;    // 文理科合并行數private int classRowSpan;      // 班級合并行數// 構造方法、getter和setter// ...
}

3. 控制器和服務層

 

java

// StudentController.java
@RestController
@RequestMapping("/api/students")
public class StudentController {@Autowiredprivate StudentService studentService;@GetMapping("/table-data")public ResponseEntity<List<TableRow>> getTableData() {List<TableRow> tableData = studentService.generateTableData();return ResponseEntity.ok(tableData);}
}
 

java

// StudentService.java
@Service
public class StudentService {// 模擬數據 - 實際應用中可以從數據庫獲取private List<Student> mockStudents = Arrays.asList(new Student("高一", "一班", "理科", "張三", "2023001"),new Student("高一", "一班", "理科", "李四", "2023002"),new Student("高一", "二班", "文科", "王五", "2023003"),new Student("高二", "三班", "理科", "趙六", "2023004"),new Student("高二", "三班", "理科", "錢七", "2023005"),new Student("高二", "四班", "文科", "孫八", "2023006"),new Student("高三", "五班", "理科", "周九", "2023007"),new Student("高三", "六班", "文科", "吳十", "2023008"));public List<TableRow> generateTableData() {// 1. 按年級、文理科、班級分組Map<String, Map<String, Map<String, List<Student>>>> groupedData = mockStudents.stream().collect(Collectors.groupingBy(Student::getGrade,Collectors.groupingBy(Student::getSubjectType,Collectors.groupingBy(Student::getClassName))));// 2. 構建表格行數據List<TableRow> tableRows = new ArrayList<>();groupedData.forEach((grade, subjectMap) -> {// 計算年級合并行數int gradeCount = subjectMap.values().stream().mapToInt(classMap -> classMap.size()).sum();subjectMap.forEach((subjectType, classMap) -> {// 計算文理科合并行數int subjectCount = classMap.size();classMap.forEach((className, students) -> {// 每個學生或空行(用于合并)if (students.isEmpty()) {// 空行處理(如果有需要)} else {// 添加學生行students.forEach(student -> {TableRow row = new TableRow();row.setGrade(grade);row.setSubjectType(subjectType);row.setClassName(className);row.setStudentId(student.getStudentId());row.setStudentName(student.getName());// 計算合并行數(只在第一行設置)if (tableRows.isEmpty() || !tableRows.get(tableRows.size() - 1).getGrade().equals(grade)) {row.setGradeRowSpan(countGradeRows(groupedData, grade));}if (tableRows.isEmpty() || !tableRows.get(tableRows.size() - 1).getGrade().equals(grade) || !tableRows.get(tableRows.size() - 1).getSubjectType().equals(subjectType)) {row.setSubjectRowSpan(countSubjectRows(groupedData, grade, subjectType));}if (tableRows.isEmpty() || !tableRows.get(tableRows.size() - 1).getGrade().equals(grade) || !tableRows.get(tableRows.size() - 1).getSubjectType().equals(subjectType) || !tableRows.get(tableRows.size() - 1).getClassName().equals(className)) {row.setClassRowSpan(students.size());}tableRows.add(row);});}});});});return tableRows;}private int countGradeRows(Map<String, Map<String, Map<String, List<Student>>>> groupedData, String grade) {return groupedData.get(grade).values().stream().mapToInt(Map::size).sum();}private int countSubjectRows(Map<String, Map<String, Map<String, List<Student>>>> groupedData, String grade, String subjectType) {return groupedData.get(grade).get(subjectType).size();}
}

前端Vue實現

1. 安裝依賴

確保已安裝Vue和axios:

bash

npm install axios

2. 表格組件實現

 

vue

<template><div class="table-container"><table class="dynamic-table"><!-- 表頭 --><thead><tr><th colspan="5" class="school-header">學校名稱</th></tr><tr><th colspan="3" class="info-header">分班信息</th><th colspan="2" class="student-header">學生信息</th></tr><tr><th>年級</th><th>文理科</th><th>班級</th><th>學號</th><th>姓名</th></tr></thead><!-- 表格內容 --><tbody><template v-for="(row, index) in tableData" :key="index"><tr><!-- 年級列 --><td v-if="shouldShowGrade(index)" :rowspan="row.gradeRowSpan">{{ row.grade }}</td><!-- 文理科列 --><td v-if="shouldShowSubject(index)" :rowspan="row.subjectRowSpan">{{ row.subjectType }}</td><!-- 班級列 --><td v-if="shouldShowClass(index)" :rowspan="row.classRowSpan">{{ row.className }}</td><!-- 學號列 --><td @click="handleStudentClick(row)">{{ row.studentId }}</td><!-- 姓名列 --><td @click="handleStudentClick(row)">{{ row.studentName }}</td></tr></template></tbody></table><!-- 學生詳情彈窗 --><div v-if="showStudentDetail" class="student-detail-modal"><div class="modal-content"><span class="close" @click="showStudentDetail = false">&times;</span><h3>學生詳細信息</h3><p>學號: {{ selectedStudent.studentId }}</p><p>年級: {{ selectedStudent.grade }}</p><p>班級: {{ selectedStudent.className }}</p><p>文理科: {{ selectedStudent.subjectType }}</p></div></div></div>
</template><script>
import axios from 'axios';export default {name: 'DynamicTable',data() {return {tableData: [],showStudentDetail: false,selectedStudent: {}};},created() {this.fetchTableData();},methods: {fetchTableData() {axios.get('/api/students/table-data').then(response => {this.tableData = response.data;// 計算合并行數this.calculateRowSpans();}).catch(error => {console.error('獲取表格數據失敗:', error);});},calculateRowSpans() {// 這里可以在后端已經計算好,前端直接使用// 如果需要在前端計算,可以在這里實現},shouldShowGrade(index) {// 如果是該年級的第一行,顯示年級單元格if (index === 0) return true;const currentGrade = this.tableData[index].grade;const prevGrade = this.tableData[index - 1].grade;return currentGrade !== prevGrade;},shouldShowSubject(index) {// 如果是該文理科的第一行,顯示文理科單元格if (index === 0) return true;const currentGrade = this.tableData[index].grade;const prevGrade = this.tableData[index - 1].grade;const currentSubject = this.tableData[index].subjectType;const prevSubject = this.tableData[index - 1].subjectType;return currentGrade !== prevGrade || currentSubject !== prevSubject;},shouldShowClass(index) {// 如果是該班級的第一行,顯示班級單元格if (index === 0) return true;const currentGrade = this.tableData[index].grade;const prevGrade = this.tableData[index - 1].grade;const currentSubject = this.tableData[index].subjectType;const prevSubject = this.tableData[index - 1].subjectType;const currentClass = this.tableData[index].className;const prevClass = this.tableData[index - 1].className;return currentGrade !== prevGrade || currentSubject !== prevSubject || currentClass !== prevClass;},handleStudentClick(student) {this.selectedStudent = {studentId: student.studentId,grade: student.grade,className: student.className,subjectType: student.subjectType};this.showStudentDetail = true;}}
};
</script><style scoped>
.table-container {width: 100%;overflow-x: auto;
}.dynamic-table {width: 100%;border-collapse: collapse;margin: 20px 0;
}.dynamic-table th, .dynamic-table td {border: 1px solid #ddd;padding: 8px;text-align: center;
}.dynamic-table th {background-color: #f2f2f2;font-weight: bold;
}.school-header {background-color: #4CAF50;color: white;font-size: 1.2em;
}.info-header {background-color: #2196F3;color: white;
}.student-header {background-color: #FF9800;color: white;
}.dynamic-table tr:nth-child(even) {background-color: #f9f9f9;
}.dynamic-table tr:hover {background-color: #f1f1f1;cursor: pointer;
}.student-detail-modal {display: block;position: fixed;z-index: 1;left: 0;top: 0;width: 100%;height: 100%;background-color: rgba(0,0,0,0.4);
}.modal-content {background-color: #fefefe;margin: 10% auto;padding: 20px;border: 1px solid #888;width: 50%;border-radius: 5px;
}.close {color: #aaa;float: right;font-size: 28px;font-weight: bold;cursor: pointer;
}.close:hover {color: black;
}
</style>

3. 主應用入口

 

javascript

// main.js
import Vue from 'vue';
import App from './App.vue';
import axios from 'axios';Vue.config.productionTip = false;// 設置axios基礎URL
axios.defaults.baseURL = 'http://localhost:8080'; // 根據實際后端地址調整new Vue({render: h => h(App),
}).$mount('#app');

完整實現說明

  1. 后端部分:
    • 定義了Student實體類存儲學生信息
    • 創建了TableRow類來表示表格行數據,包含合并行數信息
    • StudentService處理業務邏輯,將學生數據按年級、文理科、班級分組
    • 計算每個分組的合并行數
    • 提供REST API接口返回表格數據
  2. 前端部分:
    • 使用Vue組件展示動態表格
    • 通過axios從后端獲取表格數據
    • 實現合并單元格邏輯(年級、文理科、班級列)
    • 學生信息列添加點擊事件,顯示學生詳情彈窗
    • 添加了表格樣式,使界面更美觀
  3. 合并單元格邏輯:
    • 后端已經計算好每個單元格的rowspan值
    • 前端通過shouldShowGradeshouldShowSubjectshouldShowClass方法判斷是否顯示單元格
    • 使用rowspan屬性實現單元格合并
  4. 交互功能:
    • 點擊學號或姓名列會彈出學生詳情信息
    • 詳情信息包括學號、年級、班級和文理科分類

擴展建議

  1. 可以添加排序功能,允許用戶按不同列排序
  2. 可以添加分頁功能,處理大量數據
  3. 可以添加搜索功能,快速定位特定學生
  4. 可以添加導出功能,將表格導出為Excel或PDF

這個實現提供了完整的動態表格功能,包括合并單元格、點擊交互和樣式美化。根據實際需求,您可以進一步調整和擴展。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/904297.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/904297.shtml
英文地址,請注明出處:http://en.pswp.cn/news/904297.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C++學習之shell高級和正則表達式

目錄 1.正則表達式 2.C中使用正則 3.復習 4.sort命令 5.uniq命令 6.wc命令 7.grep命令 8.find命令 9.xargs命令 10.sed命令 11.awk命令 12.crontab 1.正則表達式 1 管道 使用| 將多個命令拼接在一起 原理&#xff0c;就是將前一個命令的標準輸出作為后一個…

【Vue】 實現TodoList案例(待辦事項)

目錄 組件化編碼流程&#xff08;通用&#xff09; 1.實現靜態組件&#xff1a;抽取組件&#xff0c;使用組件實現靜態頁面效果 2.展示動態數據&#xff1a; 1. 常規 HTML 屬性 3.交互——從綁定事件監聽開始 什么時候要用 event&#xff1a; 什么時候不需要用 event&am…

【Bootstrap V4系列】學習入門教程之 組件-卡片(Card)

Bootstrap V4系列 學習入門教程之 組件-卡片&#xff08;Card&#xff09; 卡片&#xff08;Card&#xff09;一、Example二、Content types 內容類型2.1 Body 主體2.2 Titles, text, and links 標題、文本和鏈接2.3 Images 圖片2.4 List groups 列表組2.5 Kitchen sink 洗滌槽…

java學習之數據結構:四、樹(代碼補充)

這部分主要是用代碼實現有序二叉樹、樹遍歷、刪除節點 目錄 1.構建有序二叉樹 1.1原理 1.2插入實現 2.廣度優先遍歷--隊列實現 3.深度優先遍歷--遞歸實現 3.1先序遍歷 3.2中序遍歷 3.3后序遍歷 4.刪除 4.1刪除葉子節點 4.2刪除有一棵子樹的節點 4.3刪除有兩棵子樹的節…

架構進階:什么是數據架構,如何理解數據架構?(華為)

數據架構是企業架構的重要組成部分,DAMA、IBM 及國內大廠對其定義各有側重。它包含數據資產目錄、數據標準、數據模型和數據分布四個組件。數據資產目錄可梳理企業數據資產,數據標準統一數據含義和規則,數據模型反映業務對象關聯關系,數據分布呈現數據流動情況。數據架構是…

Unity SpriteEditor(精靈圖片編輯器)

&#x1f3c6; 個人愚見&#xff0c;沒事寫寫筆記 &#x1f3c6;《博客內容》&#xff1a;Unity3D開發內容 &#x1f3c6;&#x1f389;歡迎 &#x1f44d;點贊?評論?收藏 &#x1f50e;SpriteEditor&#xff1a; 精靈圖片編輯器 &#x1f4cc;用于編輯2D游戲開發中使用的Sp…

【網絡原理】從零開始深入理解HTTP的報文格式(一)

本篇博客給大家帶來的是網絡HTTP協議的知識點, 重點介紹HTTP的報文格式. &#x1f40e;文章專欄: JavaEE初階 &#x1f680;若有問題 評論區見 ? 歡迎大家點贊 評論 收藏 分享 如果你不知道分享給誰,那就分享給薯條. 你們的支持是我不斷創作的動力 . 王子,公主請閱&#x1f68…

ElasticSearch深入解析(九):Object、Nested、Flattened類型

文章目錄 一、Object 類型&#xff1a;默認的嵌套對象處理方式核心原理典型場景關鍵限制 二、Nested 類型&#xff1a;解決嵌套數組的關聯查詢核心原理典型場景使用示例注意事項 三、Join 類型&#xff1a;跨文檔的父子關聯核心原理典型場景使用示例注意事項 四、Flattened 類型…

36、C#中的?法聲明參數關鍵字params,ref,out的意義及?法

在C#中&#xff0c;params、ref 和 out 是方法聲明中用于修飾參數的關鍵字&#xff0c;它們各自有不同的用途和語義。以下是它們的詳細說明和用法&#xff1a; 1、 params 關鍵字 意義 params 允許方法接受可變數量的參數&#xff0c;這些參數會被編譯為一個數組。適用于參數…

【大模型實戰篇】華為信創環境采用vllm部署QwQ-32B模型

1. 背景 本文分享在華為昇騰機器上部署QwQ-32B模型的實踐。 首先華為自己是提供了一套在信創機器&#xff08;NPU&#xff09;上部署模型的方案【1】&#xff0c;但是部署之后&#xff0c;測試發現會有輸出截斷的現象。QwQ-32B本身是支持128k的最大上下文長度&#xff0c;定位…

前端面經-VUE3篇(二)--vue3基礎知識(二)計算屬性(computed)、監聽屬性(Watch)

一、計算屬性(computed) 計算屬性&#xff08;Computed Properties&#xff09;是 Vue 中一種特殊的響應式數據&#xff0c;它能基于已有的響應式數據動態計算出新的數據。 計算屬性有以下特性&#xff1a; 自動緩存&#xff1a;只有當它依賴的響應式數據發生變化時&#xff…

[預備知識] 5. 優化理論(一)

優化理論 梯度下降&#xff08;Gradient Descent&#xff09; 數學原理與可視化 梯度下降是優化領域的基石算法&#xff0c;其核心思想是沿負梯度方向迭代更新參數。數學表達式為&#xff1a; θ t 1 θ t ? α ? θ J ( θ t ) \theta_{t1} \theta_t - \alpha \nabla…

大模型微調Fine-tuning:從概念到實踐的全面解析

目錄 引言 一、什么是大模型微調&#xff1f; 1.1 預訓練與微調的區別 1.2 微調的技術演進 二、為什么需要微調&#xff1f; 2.1 解決大模型的固有局限 2.2 微調的優勢 三、主流微調方法 3.1 全參數微調 3.2 參數高效微調&#xff08;PEFT&#xff09; 四、微調實踐指…

Docker 使用下 (二)

Docker 使用下 &#xff08;二&#xff09; 文章目錄 Docker 使用下 &#xff08;二&#xff09;前言一、初識Docker1.1 、Docker概述1.2 、Docker的歷史1.3 、Docker解決了什么問題1.4 、Docker 的優點1.5 、Docker的架構圖 二、鏡像三、容器四、數據卷4.1、數據卷的概念4.2 、…

洛谷P12238 [藍橋杯 2023 國 Java A] 單詞分類

[Problem Discription] \color{blue}{\texttt{[Problem Discription]}} [Problem Discription] Copy from luogu. [Analysis] \color{blue}{\texttt{[Analysis]}} [Analysis] 既然都是字符串前綴的問題了&#xff0c;那當然首先就應該想到 Trie \text{Trie} Trie 樹。 我們可…

pta作業中有啟發性的程序題

1 【知識點】&#xff1a;多態 函數接口定義&#xff1a; 以Student為基類&#xff0c;構建GroupA, GroupB和GroupC三個類 裁判測試程序樣例&#xff1a; #include<iostream> #include <string> using namespace std;/* 請在這里填寫答案 */int main() {const …

Scrapy框架之CrawlSpider爬蟲 實戰 詳解

CrawlSpider 是 Scrapy 框架中一個非常實用的爬蟲基類&#xff0c;它繼承自 Spider 類&#xff0c;主要用于實現基于規則的網頁爬取。相較于普通的 Spider 類&#xff0c;CrawlSpider 可以根據預定義的規則自動跟進頁面中的鏈接&#xff0c;從而實現更高效、更靈活的爬取。 Scr…

Glide 如何加載遠程 Base64 圖片

最近有個需求&#xff0c;后端給出的圖片地址并不是正常的 URL&#xff0c;而且需要一個接口去請求&#xff0c;但是返回的是 base64 數據流。這里不關心為啥要這么多&#xff0c;原因有很多&#xff0c;可能是系統的問題&#xff0c;也可能是能力問題。當然作為我們 Android 程…

004-nlohmann/json 快速認識-C++開源庫108杰

了解 nlohmann/json 的特點&#xff1b;理解編程中 “數據戰場”劃分的概念&#xff1b;迅速上手多種方式構建一個JSON對象&#xff1b; 1 特點與安裝 nlohmann/json 是一個在 github 長期霸占 “JSON” 熱搜版第1的CJSON處理庫。它的最大優點是與 C 標準庫的容器數據&#xf…

#基礎Machine Learning 算法(上)

機器學習算法的分類 機器學習算法大致可以分為三類&#xff1a; 監督學習算法 (Supervised Algorithms&#xff09;:在監督學習訓練過程中&#xff0c;可以由訓練數據集學到或建立一個模式&#xff08;函數 / learning model&#xff09;&#xff0c;并依此模式推測新的實例。…