You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django导入xls文件入库时号码字段前缀+号丢失问题

问题现象

我有一份包含SMS-no、WhatsApp-no字段的Excel文件,业务逻辑要求数据库中存储带国家代码前缀的号码。目前导入.xls文件时其余数据均可正常写入数据库,但号码前的+符号未被存入。

相关场景截图

  • Excel文件截图
    Excel文件内容截图
  • 导入后数据库存储值截图
    导入后DB存储截图
  • 添加联系人功能界面截图
    添加联系人界面截图
  • 手动添加联系人后数据库存储数据截图
    手动添加后DB存储截图

现有导入代码

以下为views.py中实现Excel导入的核心代码:

fs = FileSystemStorage()
filedata = fs.save("ImportDB.xls", myfile)
BASE_DIR = os.path.dirname(
    os.path.dirname(os.path.abspath(__file__)))
filepath = BASE_DIR + "\media\ImportDB.xls"
book = xlrd.open_workbook(filepath)
sheet = book.sheet_by_name("Sheet1")
database = MySQLdb.connect(
    host="localhost", user="root", passwd="", db="mbs")
cursor = database.cursor()
query = """INSERT INTO addcontact (f_name, l_name, add_ln1, add_ln2, country, city, zip, sms_no, whtsp_no) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)"""
for r in range(1, sheet.nrows):
        f_name = sheet.cell(r, 0).value
        l_name = sheet.cell(r, 1).value
        add_ln1 = sheet.cell(r, 2).value
        add_ln2 = sheet.cell(r, 3).value
        country = sheet.cell(r, 4).value
        city = sheet.cell(r, 5).value
        zip = sheet.cell(r, 6).value
        sms_no = sheet.cell(r, 7).value
        whtsp_no = sheet.cell(r, 8).value
        values = (f_name, l_name, add_ln1, add_ln2, country, city, zip, sms_no, whtsp_no)
        cursor.execute(query, values)
cursor.close()
database.commit()
database.close()
fs.delete(filedata)
问题根因

xlrd读取Excel单元格时,会自动将数值格式单元格中带+前缀的号码识别为浮点型数值:Excel中数值格式下的前缀+仅作为正号标记,不会被作为内容存储,因此xlrd读取后只能拿到纯数字值,写入数据库时自然丢失+前缀。而手动添加联系人功能传入的号码是字符串类型,因此可以正常保留+前缀。

修复方案

在读取号码字段后增加类型判断和格式补全逻辑,兼容数值格式、文本格式两种单元格存储场景,避免前缀丢失或重复添加:

# 循环内读取号码的逻辑替换为以下代码
# 处理sms_no字段
sms_no = sheet.cell(r, 7).value
if isinstance(sms_no, float):
    # 数值类型转整数字符串后补+前缀
    sms_no = f"+{int(sms_no)}"
elif isinstance(sms_no, str) and not sms_no.startswith('+'):
    # 文本类型无+前缀时补全
    sms_no = f"+{sms_no}"

# 处理whtsp_no字段
whtsp_no = sheet.cell(r, 8).value
if isinstance(whtsp_no, float):
    whtsp_no = f"+{int(whtsp_no)}"
elif isinstance(whtsp_no, str) and not whtsp_no.startswith('+'):
    whtsp_no = f"+{whtsp_no}"

优化建议:导入模板中可提前将号码列的单元格格式设置为「文本」类型,从源头上避免xlrd将号码识别为数值,配合上述校验逻辑可覆盖绝大多数异常场景。

内容的提问来源于stack exchange,提问作者user19491662

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 22:39:26