|
|
@ -61,25 +61,30 @@ class TemplateGridView extends StatelessWidget { |
|
|
|
final selectedNodes = controller.getSelectedNodes(); |
|
|
|
final selectedNodes = controller.getSelectedNodes(); |
|
|
|
if (selectedNodes.isEmpty) return; |
|
|
|
if (selectedNodes.isEmpty) return; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 直接从数据源获取数据 |
|
|
|
|
|
|
|
final dataSource = _TemplateItemDataSource( |
|
|
|
|
|
|
|
rows: _buildDataRows(selectedNodes, controller.displayedItems), |
|
|
|
|
|
|
|
selectedNodes: selectedNodes, |
|
|
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
// 构建表头 |
|
|
|
// 构建表头 |
|
|
|
String csvData = '序号\t'; |
|
|
|
String csvData = '序号\t'; |
|
|
|
csvData += selectedNodes.map((node) => node.name).join('\t'); |
|
|
|
csvData += selectedNodes |
|
|
|
|
|
|
|
.map((node) => node.isAttribute ? node.name.substring(1) : node.name) |
|
|
|
|
|
|
|
.join('\t'); |
|
|
|
csvData += '\n'; |
|
|
|
csvData += '\n'; |
|
|
|
|
|
|
|
|
|
|
|
// 获取所有行数据 |
|
|
|
|
|
|
|
final rows = _getGroupedData(controller); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 填充数据 |
|
|
|
// 填充数据 |
|
|
|
for (var i = 0; i < rows.length; i++) { |
|
|
|
for (final row in dataSource.rows) { |
|
|
|
csvData += '${i + 1}\t'; |
|
|
|
csvData += '${row.getCells()[0].value}\t'; // 序号 |
|
|
|
csvData += selectedNodes |
|
|
|
for (int i = 1; i < row.getCells().length; i++) { |
|
|
|
.map((node) { |
|
|
|
csvData += row.getCells()[i].value.toString(); |
|
|
|
return rows[i][node.path] ?? ''; |
|
|
|
if (i < row.getCells().length - 1) csvData += '\t'; |
|
|
|
}) |
|
|
|
} |
|
|
|
.join('\t'); |
|
|
|
|
|
|
|
csvData += '\n'; |
|
|
|
csvData += '\n'; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 保存文件 |
|
|
|
final filePath = await FilePicker.platform.saveFile( |
|
|
|
final filePath = await FilePicker.platform.saveFile( |
|
|
|
dialogTitle: '保存导出结果', |
|
|
|
dialogTitle: '保存导出结果', |
|
|
|
fileName: 'template_results.csv', |
|
|
|
fileName: 'template_results.csv', |
|
|
@ -165,60 +170,6 @@ class TemplateGridView extends StatelessWidget { |
|
|
|
return row; |
|
|
|
return row; |
|
|
|
}).toList(); |
|
|
|
}).toList(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 辅助方法:根据父路径分组数据 |
|
|
|
|
|
|
|
List<Map<String, String>> _getGroupedData(GridViewController controller) { |
|
|
|
|
|
|
|
final selectedNodes = controller.getSelectedNodes(); |
|
|
|
|
|
|
|
if (selectedNodes.isEmpty) return []; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 获取所有相关数据项 |
|
|
|
|
|
|
|
final allItems = |
|
|
|
|
|
|
|
controller.templateItems.where((item) { |
|
|
|
|
|
|
|
return selectedNodes.any((node) => item.xPath == node.path); |
|
|
|
|
|
|
|
}).toList(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 按父路径分组 |
|
|
|
|
|
|
|
final parentPaths = |
|
|
|
|
|
|
|
selectedNodes.map((node) { |
|
|
|
|
|
|
|
return node.path.substring(0, node.path.lastIndexOf('/')); |
|
|
|
|
|
|
|
}).toSet(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
final groupedData = <Map<String, String>>[]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (final parentPath in parentPaths) { |
|
|
|
|
|
|
|
// 获取该父路径下的所有项 |
|
|
|
|
|
|
|
final items = |
|
|
|
|
|
|
|
allItems.where((item) { |
|
|
|
|
|
|
|
return item.xPath.startsWith(parentPath) || |
|
|
|
|
|
|
|
item.xPath == parentPath || |
|
|
|
|
|
|
|
(item.xPath.contains('@') && |
|
|
|
|
|
|
|
item.xPath.substring(0, item.xPath.lastIndexOf('@')) == parentPath); |
|
|
|
|
|
|
|
}).toList(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 按实例分组(对于重复节点) |
|
|
|
|
|
|
|
final instanceGroups = <String, Map<String, String>>{}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (final item in items) { |
|
|
|
|
|
|
|
// 提取实例标识(如对于重复节点) |
|
|
|
|
|
|
|
final instanceId = _getInstanceId(item.xPath, parentPath); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!instanceGroups.containsKey(instanceId)) { |
|
|
|
|
|
|
|
instanceGroups[instanceId] = {'_parent': parentPath}; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
instanceGroups[instanceId]![item.xPath] = item.value; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
groupedData.addAll(instanceGroups.values); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return groupedData; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
String _getInstanceId(String fullPath, String parentPath) { |
|
|
|
|
|
|
|
// 简单实现:使用父路径后的部分作为实例ID |
|
|
|
|
|
|
|
return fullPath.substring(parentPath.length); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
class _TemplateItemDataSource extends DataGridSource { |
|
|
|
class _TemplateItemDataSource extends DataGridSource { |
|
|
|