DPS_Manage/Component/ExcelTableView.qml

103 lines
3.1 KiB
QML

// 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)
}
}
}
}
}
}
}
}