// ExcelTableView.qml import QtQuick 2.15 import QtQuick.Controls 2.15 import QtQuick.Layouts 1.15 import Excel 1.0 Item { id: root // 公共属性 property var dataModel: [] // 表格数据 property string filePath: "" // Excel文件路径 property var sheet: null // 工作表(索引或名称) property bool autoLoad: true // 文件路径变化时自动加载 property color headerColor: "#f0f0f0" // 表头背景色 property color cellColor: "white" // 单元格背景色 property int cellPadding: 8 // 单元格内边距 property int headerFontSize: 12 // 表头字体大小 property int cellFontSize: 11 // 单元格字体大小 // 信号 signal dataChanged(var newData) // 数据修改时触发 signal loadCompleted() // 数据加载完成时触发 // 表格尺寸 property real rowHeight: 40 property real colWidth: 120 // 私有属性 QtObject { id: internal property int columns: 0 property int rows: 0 } // 自动加载机制 onFilePathChanged: if(autoLoad) loadData() // 加载Excel数据 function loadData() { var result = Excel.read(filePath, sheet) if(result.length > 0) { dataModel = result processDataModel() loadCompleted() } } // 处理数据模型 function processDataModel() { internal.rows = dataModel.length internal.columns = dataModel[0] ? dataModel[0].length : 0 } // 保存数据到Excel function saveToExcel(path) { return Excel.write(path || filePath, dataModel) } // 表格布局 Flickable { anchors.fill: parent contentWidth: colWidth * internal.columns contentHeight: rowHeight * internal.rows clip: true Grid { columns: internal.columns rows: internal.rows spacing: 1 Repeater { model: dataModel // 单元格模板 Rectangle { width: colWidth height: rowHeight color: (index < internal.columns) ? headerColor : cellColor TextInput { anchors.fill: parent anchors.margins: cellPadding text: modelData ? modelData : "" font.pixelSize: (index < internal.columns) ? headerFontSize : cellFontSize verticalAlignment: Text.AlignVCenter onTextChanged: { if(index >= internal.columns) { // 更新数据模型 var row = Math.floor(index/internal.columns) var col = index % internal.columns dataModel[row][col] = text dataChanged(dataModel) } } } } } } } }