表格解析的目标
openpyxl 读取 .xlsx 的行列结构,把电子表格转成结构化记录。在知识库场景里孤立的单元格没有语义,常见做法是把「表头 + 每一行」拼成一条完整文本(如「型号:A1;功率:5W;适用电压:220V」),这样检索命中的是一条自解释的记录,而不是一串没有标签的数字。
基本信息
| 适用格式 | openpyxl 处理 .xlsx 与 .xlsm,老式 .xls 需转换或换库 |
|---|---|
| 读取模式 | data_only=True 读公式的缓存计算结果 |
| 切片单位 | 表头加行组成一条记录,或整表转 Markdown |
| 常见坑 | 合并单元格只有左上角有值,需向下填充 |
典型使用场景
- 产品参数表入库:型号、规格、兼容性一并成条,支持按型号问答
- 价目与资费表:把费率行转成文本,客服问答直接引用
- 配置对照表:设备端口与线序等宽表逐行成条,避免整体超长被截断
- 台账与清单:批量导入的资产、供应商信息做成可检索条目
- 数据质量排查:入库前检查空值率与重复行,减少脏数据进索引
读取与成条
读取与成条
import openpyxl
wb = openpyxl.load_workbook("data.xlsx", data_only=True) # 公式取缓存值
ws = wb["Sheet1"]
for row in ws.iter_rows(values_only=True):
print(row) # 逐行取值,保留列顺序
rows = list(ws.iter_rows(values_only=True))
head = rows[0] # 首行作为表头
for r in rows[1:]:
# 表头与值配对拼接,空单元格直接跳过,避免出现「字段:None」
record = ";".join(f"{h}:{v}" for h, v in zip(head, r) if v is not None)
print(record[:120])
入库形态对比
| 形态 | 优点 | 代价 |
|---|---|---|
| 整表转 Markdown | 保留行列关系,人读友好 | 宽表容易超过模型输入上限 |
| 每行一条记录 | 每条自解释,可独立检索 | 跨行统计类问题丢失整体视图 |
| 表头加行拼文本 | 检索友好,字段名自带语义 | 重复表头占用额外存储 |
| 整表一段文本 | 实现最简单 | 命中后无法定位到具体行 |
保留工作表名与表标题作为元数据:同一个文件里多张表的表头可能重名,没有来源信息时检索结果无法分辨。
入库前统计每列的空值率与重复行比例,能提前发现源文件本身的数据问题,比入库后回头清理便宜得多。