满足您对表格整理的所有要求
表格整理技能是一项面向实际任务的技能,主要用于本技能用于对用户提供的表格数据(Excel/CSV/文本表格/Markdown表格)进行智能整理,包括:自动检测并清除单元格中的空格和多余空白字符、美化排版格式、根据用户指令调整表格结构和样式,最终生成符合用户要求的规范化表格文件;数据清洗 :表格中存在大量不规则空格、首尾空格、中间多余空格;
从功能定位来看,该技能强调把分散的操作要求整理成清晰、可复用的处理流程,使用户能够围绕既定目标快速准备输入、选择执行方式并获得结构化结果。实际使用前应先确认任务范围、数据来源、运行环境、必要权限和关键参数,再依据技能说明逐步执行;
若输入条件不完整,应先补齐信息或采用保守配置,避免因错误假设导致结果偏离需求。执行过程中需要关注工具调用是否成功、接口或依赖是否可用、输出格式是否符合预期,并对异常提示、缺失字段和边界情况进行处理;涉及批量任务时,还应保存进度,避免中断后重复操作。
本技能用于对用户提供的表格数据(Excel/CSV/文本表格/Markdown表格)进行智能整理,包括:自动检测并清除单元格中的空格和多余空白字符、美化排版格式、根据用户指令调整表格结构和样式,最终生成符合用户要求的规范化表格文件。
根据用户提供的输入类型选择对应读取方式:
| 输入类型 | 读取方法 |
|---|---|
| Excel (.xlsx/.xls) | 使用 Python openpyxl 读取 |
| CSV (.csv) | 使用 Python csv 或 pandas 读取 |
| 文本表格(制表符/空格分隔) | 读取文本后解析为结构化数据 |
| Markdown表格 | 解析Markdown表格语法为数据结构 |
分析用户描述,识别需要执行的表格操作类型:
指令关键词 → 对应操作 ────────────────────────────────────── "去空格"/"清理空格"/"清除空格" → 单元格空格清理 "美化"/"排版"/"好看一点" → 格式美化(字体/边框/对齐/隔行色) "统一格式"/"规范" → 格式统一(日期/数字/小数位) "去重" → 重复行清理 "排序"/"按某列排" → 数据排序 "合并" → 工作表/单元格合并 "拆分" → 列拆分/单元格拆分 "筛选"/"过滤" → 数据筛选/过滤 "函数"/"公式" → 公式检查和规范化 "转置" → 行列互换 "加总"/"合计"/"汇总" → 添加合计行/列 "加表头"/"改表头" → 表头处理 "自适应列宽" → 自动列宽调整 "只保留"/"提取某列" → 列筛选提取 "分列" → 按分隔符分列
如果用户指令模糊,默认执行:去空格 + 自动美化排版 + 自适应列宽 三件套。
提供多级空格清理策略:
def clean_cell_spaces(value, level='standard'):
"""
单元格空格智能清理
清理级别:
- 'basic': 基础清理 — 去除首尾空格 + 合并连续空格
- 'standard': 标准清理 — 基础 + 去除全角空格、不间断空格、制表符、换行符
- 'aggressive': 激进清理 — 标准 + 去除中文间空格、标点旁多余空格
"""
if not isinstance(value, str):
return value
import re
v = value.strip()
if level == 'basic':
return re.sub(r' +', ' ', v)
v = v.replace(' ', ' ') # 全角空格
v = v.replace('xa0', ' ') # 不间断空格
v = v.replace('t', ' ')
v = v.replace('rn', ' ').replace('n', ' ').replace('r', ' ')
v = re.sub(r'[u200b-u200fufeff]', '', v) # 零宽字符
v = re.sub(r' +', ' ', v)
if level == 'aggressive':
v = re.sub(r'([u4e00-u9fff]) +([u4e00-u9fff])', r'12', v)
v = re.sub(r'([u4e00-u9fff]) +([,。、;:?!)】])', r'12', v)
v = re.sub(r'([(【「『]) +([u4e00-u9fff])', r'12', v)
return v.strip() if v else None
提供三种预设样式模板:
| 样式名 | 风格 | 适用场景 |
|---|---|---|
| clean | 简洁商务风 | 工作报告、投标文件 |
| colorful | 彩色活泼风 | 数据汇报、内部展示 |
| minimal | 极简风 | 数据分析、简单记录 |
美化操作包括:
import re
from datetime import datetime
def unify_date_format(value, target='YYYY-MM-DD'):
"""统一日期格式:支持 2024/1/5、2024年1月5日、20240105 等"""
if not isinstance(value, str):
return value
v = value.strip()
for fmt in ['%Y-%m-%d', '%Y/%m/%d', '%Y年%m月%d日', '%Y.%m.%d', '%Y%m%d']:
try:
dt = datetime.strptime(v, fmt)
return target.replace('YYYY', str(dt.year).zfill(4))
.replace('MM', str(dt.month).zfill(2))
.replace('DD', str(dt.day).zfill(2))
except ValueError:
continue
return value
def unify_text_format(value):
"""全角英数→半角,统一标点"""
if not isinstance(value, str):
return value
t = str.maketrans({
'A':'A','B':'B','C':'C','D':'D','E':'E',
'F':'F','G':'G','H':'H','I':'I','J':'J',
'K':'K','L':'L','M':'M','N':'N','O':'O',
'P':'P','Q':'Q','R':'R','S':'S','T':'T',
'U':'U','V':'V','W':'W','X':'X','Y':'Y','Z':'Z',
'a':'a','b':'b','c':'c','d':'d','e':'e',
'f':'f','g':'g','h':'h','i':'i','j':'j',
'k':'k','l':'l','m':'m','n':'n','o':'o',
'p':'p','q':'q','r':'r','s':'s','t':'t',
'u':'u','v':'v','w':'w','x':'x','y':'y','z':'z',
'0':'0','1':'1','2':'2','3':'3','4':'4',
'5':'5','6':'6','7':'7','8':'8','9':'9',
'(':'(', ')':')', ',':',', '.':'.', ':':':',
';':';', '!':'!', '?':'?', '"':'"', ''':"'",
})
return value.translate(t)
def deduplicate_rows(data, key_columns=None, keep='first'):
"""按列去重。key_columns=None则全列比较"""
if not data or len(data) < 2:
return data
header = data[0]
rows = data[1:]
seen = set()
result = [header]
for row in rows:
key = tuple(row[i] for i in key_columns if i < len(row)) if key_columns else tuple(row)
if key not in seen:
seen.add(key)
result.append(row)
return result
| 输出格式 | 方法 |
|---|---|
| Excel (.xlsx) | openpyxl 格式化输出 |
| CSV (.csv) | csv 模块 |
| Markdown表格 | 生成对齐Markdown |
| 文本表格 | 生成对齐文本 |
默认保存:~/Desktop/整理后表格_操作类型_YYYYMMDD.xlsx
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
表格整理工具 - 一键清洗 + 美化 + 格式化
依赖: pip3 install openpyxl
"""
import openpyxl
from openpyxl.styles import Font, Alignment, Border, Side, PatternFill
from openpyxl.utils import get_column_letter
import re, os
from datetime import datetime
from copy import deepcopy
def clean_spaces(value, level='standard'):
"""单元格空格清理"""
if not isinstance(value, str):
return value
v = value.strip()
if level == 'basic':
return re.sub(r' +', ' ', v)
v = v.replace('u3000', ' ') # 全角空格
v = v.replace('xa0', ' ') # 不间断空格
v = v.replace('t', ' ')
v = v.replace('rn', ' ').replace('n', ' ').replace('r', ' ')
v = re.sub(r'[u200b-u200fufeff]', '', v)
v = re.sub(r' +', ' ', v)
if level == 'aggressive':
v = re.sub(r'([u4e00-u9fff]) +([u4e00-u9fff])', r'12', v)
v = re.sub(r'([u4e00-u9fff]) +([,。、;])', r'12', v)
return v.strip() or None
def unify_date(value, out='YYYY-MM-DD'):
"""日期统一"""
if not isinstance(value, str):
return value
v = value.strip()
for fmt in ['%Y-%m-%d', '%Y/%m/%d', '%Y年%m月%d日', '%Y.%m.%d', '%Y%m%d']:
try:
dt = datetime.strptime(v, fmt)
return out.replace('YYYY', str(dt.year).zfill(4))
.replace('MM', str(dt.month).zfill(2))
.replace('DD', str(dt.day).zfill(2))
except ValueError:
continue
return value
def unify_text(value):
"""全角→半角"""
if not isinstance(value, str):
return value
t = str.maketrans({
'A':'A','B':'B','C':'C','D':'D','E':'E',
'F':'F','G':'G','H':'H','I':'I','J':'J',
'K':'K','L':'L','M':'M','N':'N','O':'O',
'P':'P','Q':'Q','R':'R','S':'S','T':'T',
'U':'U','V':'V','W':'W','X':'X','Y':'Y','Z':'Z',
'a':'a','b':'b','c':'c','d':'d','e':'e',
'f':'f','g':'g','h':'h','i':'i','j':'j',
'k':'k','l':'l','m':'m','n':'n','o':'o',
'p':'p','q':'q','r':'r','s':'s','t':'t',
'u':'u','v':'v','w':'w','x':'x','y':'y','z':'z',
'0':'0','1':'1','2':'2','3':'3','4':'4',
'5':'5','6':'6','7':'7','8':'8','9':'9',
'(':'(', ')':')', ',':',', '.':'.', ':':':',
';':';', '!':'!', '?':'?', '"':'"', ''':"'",
})
return value.translate(t)
STYLES = {
'clean': {
'hf': Font(name='微软雅黑', bold=True, size=11, color='FFFFFF'),
'hfill': PatternFill(start_color='4472C4', end_color='4472C4', fill_type='solid'),
'bf': Font(name='微软雅黑', size=10),
'af': PatternFill(start_color='D9E2F3', end_color='D9E2F3', fill_type='solid'),
'bc': 'BFBFBF',
},
'colorful': {
'hf': Font(name='微软雅黑', bold=True, size=11, color='FFFFFF'),
'hfill': PatternFill(start_color='2F5496', end_color='2F5496', fill_type='solid'),
'bf': Font(name='微软雅黑', size=10),
'af': PatternFill(start_color='E2EFDA', end_color='E2EFDA', fill_type='solid'),
'bc': '8DB4E2',
},
'minimal': {
'hf': Font(name='等线', bold=True, size=11, color='333333'),
'hfill': PatternFill(start_color='F2F2F2', end_color='F2F2F2', fill_type='solid'),
'bf': Font(name='等线', size=10),
'af': None,
'bc': 'D9D9D9',
},
}
def apply_style(ws, rows, style='clean'):
"""应用样式美化"""
s = STYLES.get(style, STYLES['clean'])
bd = Border(
left=Side(style='thin', color=s['bc']),
right=Side(style='thin', color=s['bc']),
top=Side(style='thin', color=s['bc']),
bottom=Side(style='thin', color=s['bc']),
)
ha = Alignment(horizontal='center', vertical='center', wrap_text=True)
ba = Alignment(vertical='center', wrap_text=True)
for c in range(1, ws.max_column + 1):
cell = ws.cell(row=1, column=c)
cell.font = s['hf']; cell.fill = s['hfill']
cell.alignment = ha; cell.border = bd
for r in range(2, rows + 1):
for c in range(1, ws.max_column + 1):
cell = ws.cell(row=r, column=c)
cell.font = s['bf']; cell.alignment = ba; cell.border = bd
if s['af'] and (r - 2) % 2 == 1:
cell.fill = s['af']
for c in range(1, ws.max_column + 1):
mx, cl = 0, get_column_letter(c)
for r in range(1, min(rows + 1, 100)):
v = ws.cell(row=r, column=c).value
if v:
mx = max(mx, sum(2 if 'u4e00' <= ch <= 'u9fff' else 1 for ch in str(v)))
ws.column_dimensions[cl].width = min(mx + 3, 70)
ws.freeze_panes = 'A2'
def read_excel(path):
"""读取Excel为二维列表"""
wb = openpyxl.load_workbook(path)
ws = wb.active
data = [list(row) for row in ws.iter_rows(values_only=True)]
wb.close()
return data
def write_excel(data, path, sheet='整理结果', style='clean'):
"""写入格式化Excel"""
wb = openpyxl.Workbook()
ws = wb.active
ws.title = sheet
for ri, row in enumerate(data, 1):
for ci, val in enumerate(row, 1):
ws.cell(row=ri, column=ci, value=val)
apply_style(ws, len(data), style)
wb.save(path)
return path
def run(filepath=None, table=None, ops=None, style='clean'):
"""主入口"""
data = read_excel(filepath) if filepath else (deepcopy(table) if table else None)
if not data:
raise ValueError('需提供文件路径或数据')
if not ops:
ops = ['clean_spaces']
summary = {'clean': 0, 'dedup': 0, 'date': 0, 'text': 0}
for op in ops:
if op == 'clean_spaces':
lv = ops.get('level', 'standard') if isinstance(ops, dict) else 'standard'
for ri in range(len(data)):
for ci in range(len(data[ri])):
old = data[ri][ci]
new = clean_spaces(old, lv)
if old != new: summary['clean'] += 1
data[ri][ci] = new
elif op == 'unify_date':
cols = ops.get('cols', []) if isinstance(ops, dict) else []
for ri in range(1, len(data)):
for ci in (cols or range(len(data[ri]))):
if ci < len(data[ri]):
old = data[ri][ci]
new = unify_date(old)
if old != new: summary['date'] += 1
data[ri][ci] = new
elif op == 'unify_text':
for ri in range(1, len(data)):
for ci in range(len(data[ri])):
old = data[ri][ci]
new = unify_text(old)
if old != new: summary['text'] += 1
data[ri][ci] = new
elif op == 'dedup':
if len(data) > 1:
header = data[0]; seen = set(); new_rows = [header]
for row in data[1:]:
key = tuple(row)
if key not in seen:
seen.add(key); new_rows.append(row)
else: summary['dedup'] += 1
data = new_rows
elif op == 'sort':
col = ops.get('col', 0) if isinstance(ops, dict) else 0
rev = ops.get('reverse', False) if isinstance(ops, dict) else False
if len(data) > 1:
data = [data[0]] + sorted(data[1:], key=lambda r: str(r[col]) if col < len(r) else '', reverse=rev)
ts = datetime.now().strftime('%Y%m%d_%H%M%S')
out = os.path.expanduser(f'~/Desktop/整理后表格_{ts}.xlsx')
write_excel(data, out, style=style)
return out, summary
| 用户指令关键词 | 对应操作 | 说明 |
|---|---|---|
| 去空格、清除空格、清理空白 | clean_spaces() | 标准级别清理 |
| 美化、排版、好看一点 | apply_style() | clean风格 |
| 统一日期 | unify_date() | 统一为YYYY-MM-DD |
| 统一格式、规范 | unify_text() | 全角转半角 |
| 去重、删除重复 | dedup() | 全列比较 |
| 排序、按...排 | sort() | 支持升降序 |
| 加合计、汇总 | 手写合计行 | 末行加汇总 |
| 转置 | zip转置 | 行列互换 |
| 分列 | 按分隔符拆分 | 单元格分裂 |
| 筛选、过滤 | 条件筛选 | 按条件保留 |
| 只保留某列 | 列筛选 | 仅保留指定列 |
用户: "帮我把这个Excel表格中的空格全部去掉,再美化一下" → 执行 clean_spaces(level='standard') → apply_style(style='clean')
用户: "这个表格日期格式太乱了,帮我统一格式,再按日期排序" → 对日期列执行 unify_date() → 按日期列 sort()
用户: "帮我清洗一下这张表,去重、去空格,再美化,不要隔行色" → clean_spaces() → dedup() → apply_style(minimal风格,无隔行色)
用户: "这个CSV文件转成好看的Excel,把地址列多余空格清掉,标点符号统一" → 读取CSV → 对地址列 clean_spaces() → unify_text() → 生成Excel
pip3 install openpyxl相关专题
热门下载
相关下载
精品课程
共6课时 | 54.7万人学习
共89课时 | 134.3万人学习
共49课时 | 82.7万人学习
最新文章