diff --git a/win_text_editor/lib/modules/pdf_parse/services/excel_data_adjustment_service.dart b/win_text_editor/lib/modules/pdf_parse/services/excel_data_adjustment_service.dart index 3a7ce65..f921ba6 100644 --- a/win_text_editor/lib/modules/pdf_parse/services/excel_data_adjustment_service.dart +++ b/win_text_editor/lib/modules/pdf_parse/services/excel_data_adjustment_service.dart @@ -16,6 +16,131 @@ class ExcelDataAdjustmentService { '亥': 330, }; + // 星宿数据:度数范围到星宿名称的映射 + static const List> starConstellations = [ + {'name': '娄', 'start': 34.342, 'end': 47.315}, // 34°20'32" -> 34.342°, 47°18'52" -> 47.315° + {'name': '胃', 'start': 47.315, 'end': 59.795}, // 47°18'52" -> 47.315°, 59°47'43" -> 59.795° + {'name': '昴', 'start': 59.795, 'end': 68.863}, // 59°47'43" -> 59.795°, 68°51'47" -> 68.863° + {'name': '毕', 'start': 68.863, 'end': 84.063}, // 68°51'47" -> 68.863°, 84°03'48" -> 84.063° + {'name': '觜', 'start': 84.063, 'end': 85.064}, // 84°03'48" -> 84.063°, 85°03'51" -> 85.064° + {'name': '参', 'start': 85.064, 'end': 95.680}, // 85°03'51" -> 85.064°, 95°40'47" -> 95.680° + {'name': '井', 'start': 95.680, 'end': 126.129}, // 95°40'47" -> 95.680°, 126°07'46" -> 126.129° + {'name': '鬼', 'start': 126.129, 'end': 131.118}, // 126°07'46" -> 126.129°, 131°07'06" -> 131.118° + {'name': '柳', 'start': 131.118, 'end': 147.100}, // 131°07'06" -> 131.118°, 147°06'02" -> 147.100° + {'name': '星', 'start': 147.100, 'end': 155.092}, // 147°06'02" -> 147.100°, 155°05'30" -> 155.092° + {'name': '张', 'start': 155.092, 'end': 174.165}, // 155°05'30" -> 155.092°, 174°09'53" -> 174.165° + {'name': '翼', 'start': 174.165, 'end': 191.096}, // 174°09'53" -> 174.165°, 191°05'46" -> 191.096° + {'name': '轸', 'start': 191.096, 'end': 203.901}, // 191°05'46" -> 191.096°, 203°54'05" -> 203.901° + {'name': '角', 'start': 203.901, 'end': 214.888}, // 203°54'05" -> 203.901°, 214°53'14" -> 214.888° + {'name': '亢', 'start': 214.888, 'end': 225.477}, // 214°53'14" -> 214.888°, 225°28'37" -> 225.477° + {'name': '氐', 'start': 225.477, 'end': 243.325}, // 225°28'37" -> 225.477°, 243°19'30" -> 243.325° + {'name': '房', 'start': 243.325, 'end': 248.175}, // 243°19'30" -> 243.325°, 248°10'29" -> 248.175° + {'name': '心', 'start': 248.175, 'end': 256.429}, // 248°10'29" -> 248.175°, 256°25'44" -> 256.429° + {'name': '尾', 'start': 256.429, 'end': 271.624}, // 256°25'44" -> 256.429°, 271°37'27" -> 271.624° + {'name': '箕', 'start': 271.624, 'end': 280.561}, // 271°37'27" -> 271.624°, 280°33'40" -> 280.561° + {'name': '斗', 'start': 280.561, 'end': 304.477}, // 280°33'40" -> 280.561°, 304°28'37" -> 304.477° + {'name': '牛', 'start': 304.477, 'end': 312.144}, // 304°28'37" -> 304.477°, 312°08'39" -> 312.144° + {'name': '女', 'start': 312.144, 'end': 323.812}, // 312°08'39" -> 312.144°, 323°48'42" -> 323.812° + {'name': '虚', 'start': 323.812, 'end': 333.781}, // 323°48'42" -> 323.812°, 333°46'51" -> 333.781° + {'name': '危', 'start': 333.781, 'end': 353.851}, // 333°46'51" -> 333.781°, 353°51'04" -> 353.851° + {'name': '室', 'start': 353.851, 'end': 10.603}, // 353°51'04" -> 353.851°, 10°36'11" -> 10.603° + {'name': '壁', 'start': 10.603, 'end': 22.824}, // 10°36'11" -> 10.603°, 22°49'26" -> 22.824° + {'name': '奎', 'start': 22.824, 'end': 34.342}, // 22°49'26" -> 22.824°, 34°20'32" -> 34.342° + ]; + + // 根据度数确定星宿名称 + String getStarConstellation(double degrees) { + // 处理跨越0度的情况(如室、壁、奎) + for (final constellation in starConstellations) { + final start = constellation['start'] as double; + final end = constellation['end'] as double; + + if (start <= end) { + // 正常情况:start < end + if (degrees >= start && degrees < end) { + return constellation['name'] as String; + } + } else { + // 跨越0度的情况:start > end(如室:353.851° -> 10.603°) + if (degrees >= start || degrees < end) { + return constellation['name'] as String; + } + } + } + return ''; // 如果没有找到匹配的星宿 + } + + // 从单元格值中提取度数(转换为小数形式) + double? _extractDegreesFromCell(String cellValue) { + if (cellValue.isEmpty) return null; + + // 移除 R/D 标记和多余的引号 + String cleanedValue = cellValue.replaceAll(RegExp(r'[RD]'), ''); + cleanedValue = cleanedValue.replaceAll(RegExp(r'[""]+'), ''); // 移除多余的引号 + + // 尝试多种度数格式匹配 + // 格式1: "15°30'45" 或 "15°30" + var match = RegExp(r"^(\d+)\s*°\s*(\d+)\s*(?:['′]\s*(\d{1,2})\s*)?$").firstMatch(cleanedValue); + if (match != null) { + try { + final degrees = int.parse(match.group(1)!); + final minutes = int.parse(match.group(2)!); + final seconds = match.group(3) != null ? int.parse(match.group(3)!) : 0; + + // 转换为小数度数 + return degrees + (minutes / 60.0) + (seconds / 3600.0); + } catch (e) { + return null; + } + } + + // 格式2: "15.5°" 或 "15.5" + match = RegExp(r"^(\d+\.?\d*)\s*°?\s*$").firstMatch(cleanedValue); + if (match != null) { + try { + return double.parse(match.group(1)!); + } catch (e) { + return null; + } + } + + // 格式3: "15" (纯数字) + match = RegExp(r"^(\d+)\s*$").firstMatch(cleanedValue); + if (match != null) { + try { + return double.parse(match.group(1)!); + } catch (e) { + return null; + } + } + + // 调试:如果无法匹配,输出清理后的值 + print(' - 清理后值: "$cleanedValue" (无法匹配任何度数格式)'); + + return null; + } + + // 获取列标题 + String _getColumnTitle(int colIndex) { + const Map columnTitles = { + 4: '日', + 5: '月', + 6: '水', + 7: '金', + 8: '火', + 9: '木', + 10: '土', + 11: '天', + 12: '海', + 13: '冥', + 14: '南', + 15: '北', + 16: '孛', + 17: '凯', + }; + return columnTitles[colIndex] ?? '未知'; + } + static final _degreeFormatRegex = RegExp( r"^(\d+)\s*([^\d\s°']+)\s*(\d+)\s*(?:['′]\s*(\d{1,2})\s*)?$", caseSensitive: false, @@ -31,11 +156,14 @@ class ExcelDataAdjustmentService { ) { List currentRowPalaces = List.filled(14, null); int outputCol = startCol; // 使用传入的起始列 + + // 调试日志:只输出前五行的宫宿计算信息 + bool isDebugRow = rowIndex < 5; for (int col = 4; col <= 17 && col < cells.length; col++) { final cellValue = cells[col]; - // 解析宫位 + // 1. 解析宫位 final palace = _extractPalace(cellValue); String palaceToWrite = palace; @@ -47,17 +175,58 @@ class ExcelDataAdjustmentService { previousPalaces[col] = palaceToWrite; } - currentRowPalaces[col - 4] = palaceToWrite; + // 2. 先处理原始单元格(带宫位修正) + final displayValue = _getFormattedValueWithAdjustment(cellValue, palaceToWrite); + + // 3. 基于修正后的度数进行星宿判断 + String palaceWithConstellation = palaceToWrite; + String starConstellation = ''; + double? adjustedDegrees = null; + + if (palaceToWrite.isNotEmpty) { + // 从修正后的值中提取度数 + adjustedDegrees = _extractDegreesFromCell(displayValue); + if (adjustedDegrees != null) { + starConstellation = getStarConstellation(adjustedDegrees); + if (starConstellation.isNotEmpty) { + palaceWithConstellation = '$palaceToWrite$starConstellation'; + } + } + + // 调试日志:输出宫宿计算信息 + if (isDebugRow) { + final columnTitle = _getColumnTitle(col); + final originalDegrees = _extractDegreesFromCell(cellValue); + if (adjustedDegrees != null) { + print('第${rowIndex + 1}行 ${columnTitle}: 原始坐标${originalDegrees?.toStringAsFixed(3) ?? "未知"}° -> 宫位:$palaceToWrite -> 修正后坐标${adjustedDegrees.toStringAsFixed(3)}° -> 星宿:$starConstellation -> 结果:$palaceWithConstellation'); + } else { + print('第${rowIndex + 1}行 ${columnTitle}: 无法解析修正后坐标 -> 宫位:$palaceToWrite, 星宿:$starConstellation -> 结果:$palaceWithConstellation'); + // 添加详细调试信息 + print(' - 原始值: "$cellValue"'); + print(' - 修正后值: "$displayValue"'); + print(' - 宫位: "$palaceToWrite"'); + + // 尝试从原始值提取度数 + final originalDegrees = _extractDegreesFromCell(cellValue); + if (originalDegrees != null) { + print(' - 原始值可提取度数: ${originalDegrees.toStringAsFixed(3)}°'); + } else { + print(' - 原始值无法提取度数'); + } + } + } + } + + currentRowPalaces[col - 4] = palaceWithConstellation; - // 写入宫列 + // 4. 写入宫列(包含星宿信息) sheet.cell(CellIndex.indexByColumnRow( columnIndex: outputCol, rowIndex: rowIndex - )).value = TextCellValue(palaceToWrite); + )).value = TextCellValue(palaceWithConstellation); outputCol++; - // 写入原始单元格(带修正) - final displayValue = _getFormattedValueWithAdjustment(cellValue, palaceToWrite); + // 5. 写入原始单元格(带修正) sheet.cell(CellIndex.indexByColumnRow( columnIndex: outputCol, rowIndex: rowIndex @@ -86,11 +255,21 @@ class ExcelDataAdjustmentService { adjusted = _adjustDegreeByPalace(withDegreeSymbol, palace); } - // 4. 将 R/D 标记补回(追加在末尾) - return rdFlags.isNotEmpty ? '$adjusted$rdFlags' : adjusted; + // 4. 将 R/D 标记补回(追加在末尾),确保只有一个引号 + String result = rdFlags.isNotEmpty ? '$adjusted$rdFlags' : adjusted; + + // 清理多余的引号 + result = result.replaceAll(RegExp(r'[""]+'), '"'); + + return result; } String _replaceZodiacWithDegreeSymbol(String value) { + // 首先检查是否已经是正确的度数格式 + if (value.contains('°')) { + return value; // 如果已经包含度数符号,直接返回 + } + final match = _degreeFormatRegex.firstMatch(value); if (match == null) return value; diff --git a/win_text_editor/lib/modules/pdf_parse/services/excel_deal_service.dart b/win_text_editor/lib/modules/pdf_parse/services/excel_deal_service.dart index 4fa00ba..c045696 100644 --- a/win_text_editor/lib/modules/pdf_parse/services/excel_deal_service.dart +++ b/win_text_editor/lib/modules/pdf_parse/services/excel_deal_service.dart @@ -90,7 +90,7 @@ class ExcelDealService { // 2. 添加5-18列的宫位标题和原始标题 for (int col = 4; col <= 17 && col < cells.length; col++) { final title = _columnTitles[col] ?? ''; - extendedCells.add('${title}宫'); + extendedCells.add('${title}宫'); // 宫位列现在包含星宿信息 extendedCells.add(cells[col]); } @@ -110,7 +110,8 @@ class ExcelDealService { } void _setColumnWidths(Sheet sheet) { - // 设置所有列宽(前四列 + 宫位和数据列 + 关系列) + // 设置所有列宽(前四列 + 宫位+星宿和数据列 + 关系列) + // 现在每列数据有2列:宫位+星宿、原始数据 for (var i = 0; i < 4 + (_columnTitles.length * 2) + 3; i++) { sheet.setColumnWidth(i, 8.0); } diff --git a/win_text_editor/lib/modules/pdf_parse/services/relationship_calculator_service.dart b/win_text_editor/lib/modules/pdf_parse/services/relationship_calculator_service.dart index 769e470..cc768a9 100644 --- a/win_text_editor/lib/modules/pdf_parse/services/relationship_calculator_service.dart +++ b/win_text_editor/lib/modules/pdf_parse/services/relationship_calculator_service.dart @@ -3,7 +3,6 @@ import 'package:excel/excel.dart'; class RelationshipCalculatorService { final Map _columnRedStates = {}; final List> _aspects = []; // Stores [conjunction, opposition, square, hui, banhe] for each row - int _debugRowCount = 0; // 添加调试行计数器 final Map _columnIndexes = {}; // 存储每个行星对应的列索引 static const List zodiacColumns = [ @@ -25,7 +24,6 @@ class RelationshipCalculatorService { void processEntireSheet(Sheet sheet) { _columnRedStates.clear(); _aspects.clear(); - _debugRowCount = 0; // 重置调试计数器 _columnIndexes.clear(); // 清空列索引映射 // 首先找到表头行,确定列位置 @@ -138,7 +136,7 @@ class RelationshipCalculatorService { void _calculateCoordinateRelationships(List row) { List positionsInMinutes = []; List planets = []; - bool isDebugRow = _debugRowCount > 4 && _debugRowCount < 10; + // Extract positions for all planets in minutes for (int i = 0; i < zodiacColumns.length; i++) { final columnTitle = zodiacColumns[i]; @@ -182,10 +180,6 @@ class RelationshipCalculatorService { List huis = []; // 会:度数相同(仅考虑度) List banhes = []; // 半合:相差60°(360分) - if (isDebugRow) { - print('=== 第${_debugRowCount + 1}行相位计算 ==='); - } - for (int i = 0; i < positionsInMinutes.length; i++) { for (int j = i + 1; j < positionsInMinutes.length; j++) { final diff = (positionsInMinutes[i] - positionsInMinutes[j]).abs(); @@ -194,8 +188,6 @@ class RelationshipCalculatorService { // 修复:正确计算度数,不使用取模运算 final degI = positionsInMinutes[i] ~/ 60; final degJ = positionsInMinutes[j] ~/ 60; - - final degDiff = circularDiff / 60.0; // 转换为度数用于调试 // 南北交点之间不计算任何相位关系 if ((planets[i] == '南' && planets[j] == '北') || @@ -203,81 +195,34 @@ class RelationshipCalculatorService { continue; // 跳过南北交点的相位计算 } - // 在前3行显示所有相位差信息 - if (isDebugRow) { - // 计算完整的十进制度数(包含分钟的小数部分) - final degIComplete = positionsInMinutes[i] / 60.0; - final degJComplete = positionsInMinutes[j] / 60.0; - - String output = '${planets[i]}(${degIComplete.toStringAsFixed(2)}°) vs ${planets[j]}(${degJComplete.toStringAsFixed(2)}°) - 差值: ${degDiff.toStringAsFixed(2)}°'; - - // Check for conjunction (0°±30 minutes 或 120°±30 minutes) - if (circularDiff <= 30 || (circularDiff >= 7170 && circularDiff <= 7290)) { - // 0°00' to 0°30' 或 119°30' to 120°29' - conjunctions.add('${planets[i]}${planets[j]}合'); - output += ' → 合相位'; - } - // Check for square (90°±30 minutes) - // 89°30' = 5370分钟,90°29' = 5429分钟 - else if (circularDiff >= 5370 && circularDiff <= 5429) { - // 89°30' to 90°29' - squares.add('${planets[i]}${planets[j]}刑'); - output += ' → 刑相位'; - } - // Check for opposition (180°±30 minutes) - else if (circularDiff >= 10770 && circularDiff <= 10890) { - // 179°30' to 180°29' - oppositions.add('${planets[i]}${planets[j]}冲'); - output += ' → 冲相位'; - } - // 会:度数相同(仅考虑度,不含分) - else if (degI == degJ) { - huis.add('${planets[i]}${planets[j]}会'); - output += ' → 会相位'; - } - // 半合:相差 60°±30分钟,即59°30'到60°29'之间 - // 59°30' = 3570分钟,60°29' = 3629分钟 - else if (circularDiff >= 3570 && circularDiff <= 3629) { - banhes.add('${planets[i]}${planets[j]}半合'); - output += ' → 半合相位'; - } - - print(output); - } else { - // 非调试行,静默计算相位关系 - // Check for conjunction (0°±30 minutes 或 120°±30 minutes) - if (circularDiff <= 30 || (circularDiff >= 7170 && circularDiff <= 7290)) { - // 0°00' to 0°30' 或 119°30' to 120°29' - conjunctions.add('${planets[i]}${planets[j]}合'); - } - // Check for square (90°±30 minutes) - // 89°30' = 5370分钟,90°29' = 5429分钟 - else if (circularDiff >= 5370 && circularDiff <= 5429) { - // 89°30' to 90°29' - squares.add('${planets[i]}${planets[j]}刑'); - } - // Check for opposition (180°±30 minutes) - else if (circularDiff >= 10770 && circularDiff <= 10890) { - // 179°30' to 180°29' - oppositions.add('${planets[i]}${planets[j]}冲'); - } - // 会:度数相同(仅考虑度,不含分) - else if (degI == degJ) { - huis.add('${planets[i]}${planets[j]}会'); - } - // 半合:相差 60°±30分钟,即59°30'到60°29'之间 - // 59°30' = 3570分钟,60°29' = 3629分钟 - else if (circularDiff >= 3570 && circularDiff <= 3629) { - banhes.add('${planets[i]}${planets[j]}半合'); - } + // Check for conjunction (0°±30 minutes 或 120°±30 minutes) + if (circularDiff <= 30 || (circularDiff >= 7170 && circularDiff <= 7290)) { + // 0°00' to 0°30' 或 119°30' to 120°29' + conjunctions.add('${planets[i]}${planets[j]}合'); + } + // Check for square (90°±30 minutes) + // 89°30' = 5370分钟,90°29' = 5429分钟 + else if (circularDiff >= 5370 && circularDiff <= 5429) { + // 89°30' to 90°29' + squares.add('${planets[i]}${planets[j]}刑'); + } + // Check for opposition (180°±30 minutes) + else if (circularDiff >= 10770 && circularDiff <= 10890) { + // 179°30' to 180°29' + oppositions.add('${planets[i]}${planets[j]}冲'); + } + // 会:度数相同(仅考虑度,不含分) + else if (degI == degJ) { + huis.add('${planets[i]}${planets[j]}会'); + } + // 半合:相差 60°±30分钟,即59°30'到60°29'之间 + // 59°30' = 3570分钟,60°29' = 3629分钟 + else if (circularDiff >= 3570 && circularDiff <= 3629) { + banhes.add('${planets[i]}${planets[j]}半合'); } } } - if (isDebugRow) { - print('--- 第${_debugRowCount + 1}行计算完成 ---\n'); - } - _aspects.add([ conjunctions.join(', '), oppositions.join(', '), @@ -285,8 +230,6 @@ class RelationshipCalculatorService { huis.join(', '), banhes.join(', '), ]); - - _debugRowCount++; // 增加调试行计数器 } void _addAspectMarkers(Sheet sheet) {