diff --git a/README.md b/README.md index 9626ca8..4765d7c 100644 --- a/README.md +++ b/README.md @@ -40,3 +40,5 @@ V2:zip 解压后包含 `Patients_info.csv`,并按患者目录分别保存检 - 未检测到内容汇总表 “未检测到内容汇总”会收集标准字段全部为 `Not_Find`、但存在未匹配检测内容的记录,并按检测原因排序汇总。 + +未匹配检测内容会被规范化为独立列:表头为未匹配检测项目名,数据行仅保存对应检测值。 diff --git a/app/main.py b/app/main.py index 6eff762..7f5d340 100644 --- a/app/main.py +++ b/app/main.py @@ -440,8 +440,9 @@ def _page_shell(body: str, subtitle: str = "\u4e0a\u4f20\u201c\u5f85\u5904\u7406 .table-wrap {{ width: 100%; max-width: 100%; - max-height: 620px; - overflow: auto; + max-height: 380px; + overflow-x: auto; + overflow-y: scroll; background: #fff; }} table {{ diff --git a/app/processor.py b/app/processor.py index f2736d6..91df4df 100644 --- a/app/processor.py +++ b/app/processor.py @@ -341,6 +341,7 @@ def _postprocess_workbook( ) -> None: workbook = load_workbook(path) try: + _normalize_unmatched_columns(workbook) summary_records = _collect_summary_records(workbook) if not include_unmatched_items: @@ -362,6 +363,46 @@ def _postprocess_workbook( workbook.close() +def _normalize_unmatched_columns(workbook) -> None: + for sheet in workbook.worksheets: + if sheet.title == "未检测到内容汇总" or sheet.max_row < 2: + continue + + header = [_cell_text(sheet.cell(1, col).value) for col in range(1, sheet.max_column + 1)] + unmatched_index = _find_header_index(header, "未匹配检测内容") + if unmatched_index is None: + continue + + marker_col = unmatched_index + 1 + parsed_rows: list[dict[str, str]] = [] + item_names: list[str] = [] + for row_index in range(2, sheet.max_row + 1): + raw_values = [ + _cell_text(sheet.cell(row_index, col).value) + for col in range(marker_col, sheet.max_column + 1) + ] + parsed = _parse_unmatched_items([value for value in raw_values if value]) + parsed_rows.append(parsed) + for item_name in parsed: + if item_name not in item_names: + item_names.append(item_name) + + if sheet.max_column >= marker_col: + sheet.delete_cols(marker_col, sheet.max_column - marker_col + 1) + + sheet.cell(1, marker_col).value = "未匹配检测内容" + sheet.cell(1, marker_col).font = Font(bold=True) + for offset, item_name in enumerate(item_names, start=1): + cell = sheet.cell(1, marker_col + offset) + cell.value = item_name + cell.font = Font(bold=True) + + for row_index, parsed in enumerate(parsed_rows, start=2): + sheet.cell(row_index, marker_col).value = "" + for offset, item_name in enumerate(item_names, start=1): + sheet.cell(row_index, marker_col + offset).value = parsed.get(item_name, "") + + def _collect_summary_records(workbook) -> list[dict[str, object]]: records: list[dict[str, object]] = [] for sheet in workbook.worksheets: @@ -380,12 +421,13 @@ def _collect_summary_records(workbook) -> list[dict[str, object]]: _cell_text(sheet.cell(row_index, col).value) for col in range(5, unmatched_col + 1) ] - unmatched_values = [ - _cell_text(sheet.cell(row_index, col).value) - for col in range(unmatched_col + 1, sheet.max_column + 1) - ] - unmatched_values = [value for value in unmatched_values if value] - if not unmatched_values: + item_values = { + _cell_text(sheet.cell(1, col).value): _cell_text(sheet.cell(row_index, col).value) + for col in range(unmatched_col + 2, sheet.max_column + 1) + if _cell_text(sheet.cell(1, col).value) + } + item_values = {name: value for name, value in item_values.items() if value} + if not item_values: continue if not _all_standard_values_missing(standard_values): continue @@ -396,7 +438,7 @@ def _collect_summary_records(workbook) -> list[dict[str, object]]: "sample_time": base_values[2], "reason": base_values[3], "sheet": sheet.title, - "items": _parse_unmatched_items(unmatched_values), + "items": item_values, } ) return records