excel-split

Polar Sponsor
爱发电 赞助
.NET 9.0

辅助处理excel表格,按列拆分大表为多个文件

这种技能遵循[excel-seafe-workflow]的四步法. .

功能概述

这种技能遵循[excel-seafe-workflow]的四步法. .是一项面向实际任务的技能,主要用于Grouping使用熊猫, fan-out 使用 lxml terperse 单色-scan 多步输出.;本技能遵循 [[excel-sefefect-workflow]] 四步法;

核心要点

  • 分组用熊猫, 分流用 lxml i。
  • 它将相关步骤、工具调用和结果整理方式集中到统一流程中,帮助使用者更快完成目标并减少重复操作。
  • 使用时应结合输入条件选择合适的执行方式,核对必要参数、依赖环境与输出内容,并按原始要求处理异常情况。

使用与执行

从功能定位来看,该技能强调把分散的操作要求整理成清晰、可复用的处理流程,使用户能够围绕既定目标快速准备输入、选择执行方式并获得结构化结果。实际使用前应先确认任务范围、数据来源、运行环境、必要权限和关键参数,再依据技能说明逐步执行;若输入条件不完整,应先补齐信息或采用保守配置,避免因错误假设导致结果偏离需求。

结果检查与注意事项

执行过程中需要关注工具调用是否成功、接口或依赖是否可用、输出格式是否符合预期,并对异常提示、缺失字段和边界情况进行处理;涉及批量任务时,还应保存进度,避免中断后重复操作。该技能适合用于一次性任务,也可以接入自动化工作流,与其他技能或上层代理配合完成更完整的业务链路;在组合使用时,应明确每一步的输入输出关系,并避免不同步骤之间出现参数冲突。

This skill follows [[excel-safe-workflow]] four-step method. Grouping uses pandas, fan-out uses lxml iterparse single-scan multi-output. 本技能遵循 [[excel-safe-workflow]] 四步法。分组用 pandas,分流用 lxml iterparse 一次扫描多路输出。

Excel Split / Excel 拆分

功能

把一张大表按某列的值拆成 N 个独立文件。

总表 (33万行)
  │
  │ 按"申请人"拆分 Top 10
  │
  ├── 上海诺基亚贝尔.xlsx    (1859行)
  ├── 上海泰康网络.xlsx      (1301行)
  ├── ... (8个)
  └── 其他.xlsx              (283145行)

第零步:需求解析

要素 用户说 默认值
拆分列 "按申请人拆""按年份分" 必须明确
Top N "前10个""最多的20个" 20
输出目录 "放到 split 文件夹" {原文件名}_split_{列名}/

第一步:勘察

import pandas as pd

FILE = '目标文件.xlsx'
SPLIT_COL = '列名'

df = pd.read_excel(FILE)
counts = df[SPLIT_COL].value_counts()
print(f'总行数: {len(df)}, 唯一值: {len(counts)}')
print(f'Top 10:')
for k, v in counts.head(10).items():
    print(f'  {k}: {v} 行')

第二步:规划

  • Top N 限制:唯一值太多时(>50),只拆 Top N,其余合并为"其他"
  • 先压实:如果文件之前做过去重/筛选(有行号空隙),先压实再拆分,否则 pandas 扫描行数会偏高
  • 输出目录:{原文件名}_split/
  • 文件命名:{拆分值}.xlsx(自动清理非法字符)

第三步:执行

核心思路:一次 iterparse 流式解析 XML,按行分流到各输出缓冲区,避免重复解析。

import pandas as pd, zipfile, os, shutil, re, time
from lxml import etree
from collections import defaultdict

S_NS = 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'

FILE = '目标文件.xlsx'
SPLIT_COL = '列名'
TOP_N = 20
OUTPUT_DIR = FILE.replace('.xlsx', f'_split_{SPLIT_COL}')

# ====== 3.1 pandas 分组 ======
print(f'[1/4] pandas 分组...')
df = pd.read_excel(FILE).dropna(how='all')  # 去掉空行(如有间隙)
total = len(df)
counts = df[SPLIT_COL].value_counts()
top_keys = set(counts.head(TOP_N).index.tolist()) if len(counts) > TOP_N else set(counts.index)

row_to_file = {}
file_sizes = defaultdict(int)
for key in top_keys:
    safe = str(key).replace('/', '_').replace('\', '_').replace(':', '_')[:80]
    indices = df.index[df[SPLIT_COL] == key].tolist()
    for i in indices:
        row_to_file[i + 2] = f'{safe}.xlsx'
    file_sizes[f'{safe}.xlsx'] = len(indices)

other = df.index[~df[SPLIT_COL].isin(top_keys)].tolist()
if other:
    for i in other:
        row_to_file[i + 2] = '其他.xlsx'
    file_sizes['其他.xlsx'] = len(other)

print(f'  将生成 {len(file_sizes)} 个文件')

# ====== 3.2 解压 ======
print(f'[2/4] 解压...')
TMP = FILE.replace('.xlsx', '_split_tmp')
if os.path.exists(TMP): shutil.rmtree(TMP)
os.makedirs(TMP)
with zipfile.ZipFile(FILE, 'r') as z:
    z.extractall(TMP)

worksheets_dir = os.path.join(TMP, 'xl', 'worksheets')
orig_sheet = None
for sf in sorted(os.listdir(worksheets_dir)):
    if sf.endswith('.xml') and sf.startswith('sheet'):
        orig_sheet = os.path.join(worksheets_dir, sf)
        break

# ====== 3.3 iterparse 流式分流 ======
print(f'[3/4] 流式分流...')
row_xml = defaultdict(list)
header_xml = []

tag = f'{{{S_NS}}}row'
for event, elem in etree.iterparse(orig_sheet, tag=tag):
    r = int(elem.get('r'))
    row_str = etree.tostring(elem, encoding='unicode')

    if r == 1:  # 表头行
        header_xml.append(row_str)
    elif r in row_to_file:
        row_xml[row_to_file[r]].append(row_str)

    elem.clear()
    while elem.getprevious() is not None:
        del elem.getparent()[0]

# ====== 3.4 生成输出文件 ======
print(f'[4/4] 生成输出文件...')
os.makedirs(OUTPUT_DIR, exist_ok=True)

# 构建 sheet XML 模板( 前后的结构)
tree_orig = etree.parse(orig_sheet, etree.XMLParser(huge_tree=True))
full_xml = etree.tostring(tree_orig.getroot(), encoding='unicode')
sd_start = full_xml.find('')
prefix = full_xml[:sd_start]
suffix = full_xml[sd_end + len(''):]

for idx, (fname, rows) in enumerate(sorted(row_xml.items(), key=lambda x: -len(x[1]))):
    fpath = os.path.join(OUTPUT_DIR, fname)
    all_rows = ''.join(header_xml) + ''.join(rows)
    new_xml = f'{prefix}{all_rows}{suffix}'

    with open(orig_sheet, 'w', encoding='utf-8') as f:
        f.write(new_xml)

    with zipfile.ZipFile(fpath, 'w', zipfile.ZIP_DEFLATED) as zout:
        for dirpath, _, filenames in os.walk(TMP):
            for fn in filenames:
                full = os.path.join(dirpath, fn)
                zout.write(full, os.path.relpath(full, TMP).replace('\', '/'))

shutil.rmtree(TMP)
print(f'完成,输出: {OUTPUT_DIR}/')

第四步:验证

import pandas as pd, os

total_out = 0
for f in os.listdir(OUTPUT_DIR):
    if not f.endswith('.xlsx'): continue
    fp = os.path.join(OUTPUT_DIR, f)
    df = pd.read_excel(fp).dropna(how='all')
    total_out += len(df)

    if f != '其他.xlsx':
        key = f.replace('.xlsx', '')
        bad = df[df[SPLIT_COL] != key].shape[0]
        if bad: print(f'  ❌ {f}: {bad} 行错配')

print(f'输出总行: {total_out} (期望 {total})')

性能

文件 行数 输出文件数 pandas扫描 iterparse分流 生成打包 总耗时
测试文件 914 6 1s 0s 0s 1s
主文件 29万 11 82s 51s 258s ~6.5min

生成打包阶段耗时较长是因为每个输出文件都包含完整的 sharedStrings.xml(273MB),11 个文件约 3GB 压缩量。迭代次数越多,此阶段越慢。

注意事项

  1. 拆分前先压实:如果文件做过去重/筛选有行号空隙,先用 [[excel-delete]] 中的压实功能
  2. 共享字符串膨胀:每个输出文件继承完整的 sharedStrings,N 个文件 = N × 原始大小
  3. 大文件建议限制 Top N:默认 Top 20,避免生成数百个文件
  4. iterparse 内存友好:一次只保有一个 row 元素,33万行约占用 100-200MB 内存
  5. 操作前必备份:遵循 [[excel-safe-workflow]] 第零步——拆分前自动备份原文件(时间戳命名),成功后保留最新3份

相关专题

更多
Excel制作交互图表的方法 Excel交互式的图表教程大全
Excel制作交互图表的方法 Excel交互式的图表教程大全

Excel交互式图表可通过四种方法实现:一、用切片器控制数据透视图;二、结合下拉列表与INDEX-MATCH动态引用;三、用选项按钮绑定图表系列;四、利用动态命名区域配合OFFSET函数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2026.01.04

1820

12

excel制作动态图表教程
excel制作动态图表教程

本专题整合了excel制作动态图表相关教程,阅读专题下面的文章了解更多详细教程。

2025.12.29

205

12

Excel图表制作全流程
Excel图表制作全流程

本专题整合了excel制作图表的相关教程,阅读专题下面的文章了解更多详细内容。

2025.12.23

240

7

excel xls与xlsx的区别
excel xls与xlsx的区别

本专题整合了excel中xls与xlsx的区别,阅读专题下面的文章了解更多详细内容。

2025.12.23

357

10

excel 绝对值
excel 绝对值

本专题整合了excel绝对值相关教程,阅读专题下面的文章了解更多详细内容。

2025.12.09

839

10

Excel如何制作一个动态交互式图表
Excel如何制作一个动态交互式图表

首先通过准备数据源并创建基础图表,再插入表单控件实现用户交互,接着使用INDEX公式提取对应数据,然后将图表数据源指向动态区域,最后优化布局与标题实现动态更新。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2025.11.28

1738

9

excel算方差教程
excel算方差教程

计算方差的步骤依次为:1. 计算平均值;2. 计算差异的平方;3. 求和平方值;4. 除以数据点数。想要了解更多相关内容,请阅读专题下面的文章。

2025.05.27

4049

13

怎么用excel制作标签
怎么用excel制作标签

用 Excel 制作标签,若为普通工作表标签,可右键单击标签选 “重命名” 来修改名称;选 “标签颜色” 设置颜色用于区分。若制作数据标签,比如地址标签,先在 Excel 整理好数据,再借助 Word 的邮件合并功能。在 Word 中依次操作:“邮件” 选项卡→“开始邮件合并”→“标签”,选好标签类型,导入 Excel 数据并设置格式,完成后打印 。

2025.04.14

6551

9

excel提取想要的数据
excel提取想要的数据

提取方法有很多种。直接定位:使用“定位”功能选择所需数据。筛选:根据条件筛选数据,显示满足条件的单元格。条件格式:突出显示满足特定条件的数据单元格。高级筛选:指定条件,将提取的数据粘贴到目标范围。公式:使用 index、if、sumif、countif 等函数从数据中提取值。vba 宏:编写脚本以自动提取数据,满足特定条件。

2025.01.08

5430

13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Excel 教程
Excel 教程

共162课时 | 45.4万人学习

成为PHP架构师-自制PHP框架
成为PHP架构师-自制PHP框架

共28课时 | 3.6万人学习