zhizhijie
2026-09-20 35d098a89613c96179391178b7f8143dec393ada
docs/Ͷ×Ê/¹¤¾ß/ÊÐÖÝÔ±¨½âÎö.py
@@ -77,39 +77,8 @@
def pick_columns(cell, nrows, ncols, merges=None):
    """按表头关键字定位列;同一字段命中多次时,取“行号最小、其次是命中词最短”的那个。
    ä¸¤çº§è¡¨å¤´ï¼ˆç»„表头)处理:若某字段的命中落在**跨多列的合并单元格**里,说明它是组表头,
    ä¸èƒ½ç›´æŽ¥å½“成该字段的列;此时在本合并区内排除“其它字段更深的子表头”所占的列,
    è‹¥åªå‰©å”¯ä¸€ä¸€åˆ—,则该列就是本字段的列。
    ä¾‹ï¼šé„‚州《企业月报汇总》R5 ç»„表头「自年初累计完成投资(万元)」合并 I:J:K,
        å­è¡¨å¤´ I=本年计划投资(万元)、J=合计、K=其中:本月完成投资 â†’
        ã€Œè‡ªå¹´åˆç´¯è®¡ã€åº”落在 J(与投资系统 G åˆ— 5507.5 ä¸€è‡´ï¼‰ï¼Œè€Œä¸æ˜¯ I(8000,那其实是本年计划投资)。
    """
    hits = F.scan_fields(cell, nrows, ncols)
    best = {}
    for f in FIELDS:
        if f in hits:
            best[f] = sorted(hits[f], key=lambda h: (h[0], len(h[2])))[0]
    cols = {}
    for f, h in best.items():
        row1, letter, _txt = h
        c0 = F.colindex(letter)
        span = F.merge_span(merges, row1, c0)
        if span and (span[1] - span[0]) > 1:
            taken = set()
            for f2, h2 in best.items():
                if f2 == f or h2[0] <= row1:
                    continue
                c2 = F.colindex(h2[1])
                if span[0] <= c2 < span[1]:
                    taken.add(c2)
            free = [c for c in range(span[0], span[1]) if c not in taken]
            if len(free) == 1:
                cols[f] = free[0]
                continue
        cols[f] = c0
    return cols, hits
    """按表头定位列(含两级表头消歧)——实现见 æ ¼å¼æŽ¢æµ‹.py çš„ pick_columns,保证两处口径一致。"""
    return F.pick_columns(cell, nrows, ncols, merges, fields=FIELDS)
def parse_sheet(cell, nrows, ncols, city=None, merges=None):
@@ -254,7 +223,8 @@
                               for k in ('自开始建设累计', '自年初累计', '本月完成'))
                    ok = '✅ ä¸€è‡´' if same else '⚠️ ä¸ä¸€è‡´'
                ck = {'品类': body_key, '市州': city, '文件': f, '工作表': nm, '状态': 'OK',
                      '项目行数': len(rows), '合计行': '', '一致性': ok}
                      '项目行数': len(rows), '合计行': '', '一致性': ok,
                      '列位': ','.join('%s=%s' % (k, v) for k, v in (extra.get('列位') or {}).items())}
                for k in ('自开始建设累计', '自年初累计', '本月完成'):
                    ck['求和_' + k] = sums[k]
                if sub:
@@ -295,7 +265,18 @@
            *(pretty(s[f]) for f in ('总投资', '自开始建设累计', '本年计划投资', '自年初累计', '本月完成'))))
    report.append('')
    ck_cols = ['品类', '市州', '文件', '工作表', '状态', '项目行数', '一致性', '合计行',
    report.append('## å„源文件识别到的列位(**按表头关键字定位,不是固定列号**)')
    report.append('')
    report.append('| å“ç±» | æ–‡ä»¶ | å·¥ä½œè¡¨ | é¡¹ç›®åç§° | æ€»æŠ•资 | è‡ªå¼€å§‹å»ºè®¾ç´¯è®¡ | æœ¬å¹´è®¡åˆ’投资 | è‡ªå¹´åˆç´¯è®¡ | æœ¬æœˆå®Œæˆ |')
    report.append('| --- | --- | --- | --- | --- | --- | --- | --- | --- |')
    _key5 = ('项目名称', '总投资', '自开始建设累计', '本年计划投资', '自年初累计', '本月完成')
    for ck in checks:
        _cm = dict(kv.split('=', 1) for kv in (ck.get('列位') or '').split(',') if '=' in kv)
        report.append('| %s | %s | %s | %s |' % (ck.get('品类', ''), ck.get('文件', '')[:34], ck.get('工作表', '')[:12],
                                                 ' | '.join(_cm.get(k, '—') for k in _key5)))
    report.append('')
    ck_cols = ['品类', '市州', '文件', '工作表', '状态', '项目行数', '一致性', '合计行', '列位',
               '求和_自开始建设累计', '求和_自年初累计', '求和_本月完成',
               '合计_自开始建设累计', '合计_自年初累计', '合计_本月完成']
    p_ck = os.path.join(out, '解析校验_%s.tsv' % a.month)