处理 Excel 数据导入导出时,单元格类型不匹配是常见痛点:编号前导零丢失、身份证号变成科学计数法、文本数字无法参与计算。这些问题的根源在于单元格底层存储类型与业务预期不一致。本文基于 Free Spire.XLS for Python 免费库,提供几种实用的数值与文本双向转换方案,无需安装 Office 组件。
一、环境准备
通过 pip 安装免费版本:- pip install Spire.XLS.Free
复制代码 免费版对工作表数量和数据行数有限制,适合小型项目和日常开发。引入核心类:
二、核心属性辨析
在转换前,需要理解 CellRange 对象的三个关键属性:
- Text:单元格的显示文本,即格式化后的字符串。
- NumberValue:数值形式的浮点值,仅数值/日期类型有效。
- NumberFormat:数字格式代码,如 "0.00"、"@"、"yyyy-MM-dd"。
简单理解:NumberFormat 决定显示格式,NumberValue 决定存储本质。只修改 NumberFormat 不改变底层数据类型,这是常见陷阱。
三、数值转文本的三种方案
方案一:设置文本格式代码(推荐)
直接将单元格 NumberFormat 设为 "@",解决长数字显示科学计数法问题,底层仍是数值类型。- workbook = Workbook()
- workbook.LoadFromFile("库存.xlsx")
- sheet = workbook.Worksheets[0]
- sheet.Range["D2:E11"].NumberFormat = "@"
- workbook.SaveToFile("文本.xlsx", ExcelVersion.Version2016)
- workbook.Dispose()
复制代码 特点:仅改变显示规则,不会出现绿色三角标记,后续仍可参与数值计算。
方案二:重读重写彻底转换类型
先设置文本格式,再通过 Text 属性重新写入值,从存储层面转为文本类型,适合导出给外部系统(如银行报盘)。- workbook = Workbook()
- workbook.LoadFromFile("库存.xlsx")
- sheet = workbook.Worksheets[0]
- data_range = sheet.Range["D2:E11"]
- for cell in data_range:
- cell.NumberFormat = "@"
- cell.Text = str(cell.Value) if cell.Value is not None else ""
- workbook.SaveToFile("重写文本.xlsx", ExcelVersion.Version2016)
- workbook.Dispose()
复制代码 特点:Excel 中会显示文本类型的绿色三角标记,底层存储为字符串。
方案三:保留前导零的特殊处理
编号类数据通常需要固定长度,转换时统一格式化:- for cell in sheet.Range["A2:A6"]:
- try:
- num = float(cell.Value)
- cell.NumberFormat = "@"
- cell.Text = f"{num:06.0f}" # 6位编号,不足补零
- except (ValueError, TypeError):
- continue
复制代码
四、文本转数值的三种方案
Free Spire.XLS 提供原生 ConvertToNumber() 方法,自动识别文本数字并转为数值类型。
方案一:原生方法批量转换
直接对区域调用,一行代码完成批量处理,自动跳过空单元格和非数字内容。- workbook = Workbook()
- workbook.LoadFromFile("重写文本.xlsx")
- sheet = workbook.Worksheets[0]
- sheet.Range["A2:E11"].ConvertToNumber()
- workbook.SaveToFile("文本转数字.xlsx", ExcelVersion.Version2016)
- workbook.Dispose()
复制代码
方案二:转换同时指定精度格式
调用转换后直接设置数字格式,无需遍历:- data_range = sheet.Range["D2:E11"]
- data_range.ConvertToNumber()
- data_range.NumberFormat = "0.00"
复制代码
方案三:整列自动范围批量转换
对于不确定行数的整列数据,先自动识别有效数据边界,避免遍历空单元格:- last_row = sheet.Columns[2].LastRow # 列索引从0开始
- data_range = sheet.Range[2, 3, last_row, 3] # 行、列索引从1开始
- data_range.ConvertToNumber()
复制代码
五、总结
数值转文本只需将 NumberFormat 设为 "@",配合重写可彻底转换类型;文本转数值调用 ConvertToNumber() 即可批量处理。整个操作无需 Microsoft Office,API 简洁,特别适合在 Python 项目中处理 Excel 格式清洗与数据导出的场景。 |