docs/Ͷ×Ê/¹¤¾ß/¸ñʽ̽²â.py
@@ -106,6 +106,45 @@
    return n - 1
def sheet_merges(path):
    """返回 {sheet_name: [(rlo, rhi, clo, chi), ...]}(0 åŸºã€å³å¼€ï¼‰ã€‚
    ç”¨äºŽè¯†åˆ«ã€Œä¸¤çº§è¡¨å¤´ã€ï¼šç»„表头(跨多列的合并单元格)不能直接当成某字段的列。
    è¯»ä¸åˆ°åˆå¹¶ä¿¡æ¯æ—¶è¿”回已解析到的部分(不抛异常)。
    """
    with open(path, 'rb') as fh:
        magic = fh.read(4)
    out = {}
    try:
        if magic[:4] == b'PK\x03\x04':
            if openpyxl is None:
                return out
            wb = openpyxl.load_workbook(path, data_only=True)
            for nm in wb.sheetnames:
                ws = wb[nm]
                out[nm] = [(r.min_row - 1, r.max_row, r.min_col - 1, r.max_col)
                           for r in ws.merged_cells.ranges]
            wb.close()
        else:
            if xlrd is None:
                return out
            bk = xlrd.open_workbook(path, formatting_info=True)
            for si in range(bk.nsheets):
                sh = bk.sheet_by_index(si)
                out[sh.name] = list(getattr(sh, 'merged_cells', []) or [])
    except Exception:
        return out
    return out
def merge_span(merges, row1, col0):
    """该单元格(1 åŸºè¡Œå·ã€0 åŸºåˆ—号)所在合并区的 (列0èµ·, åˆ—0止右开);不在合并区返回 None。"""
    for (rlo, rhi, clo, chi) in (merges or ()):
        if rlo <= row1 - 1 < rhi and clo <= col0 < chi:
            return (clo, chi)
    return None
def open_sheets(path):
    """返回 [(sheet_name, nrows, ncols, cell_fn), ...]。