Browse Source

增加导出csv功能

master
hejl 2 months ago
parent
commit
801e326f4e
  1. 2
      win_text_editor/lib/app/modules/content_search/content_search_service.dart
  2. 74
      win_text_editor/lib/app/modules/content_search/results_view.dart

2
win_text_editor/lib/app/modules/content_search/content_search_service.dart

@ -171,7 +171,7 @@ class ContentSearchService { @@ -171,7 +171,7 @@ class ContentSearchService {
try {
final lines = await file.readAsLines();
for (int i = 0; i < lines.length; i++) {
final line = lines[i];
final line = lines[i].trim();
final matches = pattern.allMatches(line);
if (matches.isNotEmpty) {

74
win_text_editor/lib/app/modules/content_search/results_view.dart

@ -4,6 +4,8 @@ import 'package:syncfusion_flutter_datagrid/datagrid.dart'; @@ -4,6 +4,8 @@ import 'package:syncfusion_flutter_datagrid/datagrid.dart';
import 'package:path/path.dart' as path;
import 'package:win_text_editor/app/modules/content_search/content_search_controller.dart';
import 'package:win_text_editor/app/modules/content_search/content_search_service.dart';
import 'package:file_picker/file_picker.dart';
import 'dart:io';
class ResultsView extends StatelessWidget {
const ResultsView({super.key});
@ -20,7 +22,77 @@ class ResultsView extends StatelessWidget { @@ -20,7 +22,77 @@ class ResultsView extends StatelessWidget {
controller.clearResults();
}
return Card(child: _buildResultsGrid(controller));
return Card(
child: GestureDetector(
onSecondaryTapDown: (details) {
_showContextMenu(context, details.globalPosition, controller);
},
child: _buildResultsGrid(controller),
),
);
}
Future<void> _showContextMenu(
BuildContext context,
Offset position,
ContentSearchController controller,
) async {
//
final renderBox = context.findRenderObject() as RenderBox;
final localPosition = renderBox.globalToLocal(position);
//
final result = await showMenu<String>(
context: context,
position: RelativeRect.fromLTRB(
position.dx,
position.dy,
position.dx + renderBox.size.width - localPosition.dx,
position.dy + renderBox.size.height - localPosition.dy,
),
items: [const PopupMenuItem<String>(value: 'export', child: Text('导出(csv)'))],
);
//
if (result == 'export' && context.mounted) {
try {
await _exportToCsv(controller);
} catch (e) {
if (context.mounted) {
ScaffoldMessenger.of(
context,
).showSnackBar(SnackBar(content: Text('导出失败: ${e.toString()}')));
}
}
}
}
Future<void> _exportToCsv(ContentSearchController controller) async {
String csvData = '';
if (controller.searchMode == SearchMode.locate) {
csvData = '文件(行号),内容\n';
for (var result in controller.results) {
csvData +=
'${path.basename(result.filePath)}(${result.lineNumber}),${result.lineContent.replaceAll(',', '')}\n';
}
} else {
csvData = '关键词,匹配数量\n';
for (var result in controller.results) {
csvData += '${result.filePath},${result.lineNumber}\n';
}
}
final filePath = await FilePicker.platform.saveFile(
dialogTitle: '保存导出结果',
fileName: 'search_results.csv',
type: FileType.custom,
allowedExtensions: ['csv'],
);
if (filePath != null) {
final file = File(filePath);
await file.writeAsString(csvData);
}
}
Widget _buildResultsGrid(ContentSearchController controller) {

Loading…
Cancel
Save