使用 Python 将 Excel 数据批量导入到数据库中(SQLite)

一、应用场景与方案优势

适用场景

  1. 企业 Excel 报表数据迁移至数据库持久化存储;
  2. 自动化办公:定期将 Excel 导出数据同步到数据库;
  3. 轻量级数据中台:多 Excel 文件整合入库,方便后续查询分析;
    4.测试数据构造:快速将 Excel 测试数据导入数据库。

方案核心优势

  1. 无环境依赖:无需安装 Microsoft Office/WPS,纯 Python 库解析 Excel;
  2. 多工作表适配:自动遍历 Excel 所有 sheet,无需手动指定;
  3. 动态建表:根据 Excel 表头自动生成数据库表结构;
  4. 安全稳定:参数化 SQL 防注入,事务管理保证数据一致性;
  5. 轻量免费:适用于中小型 Excel 文件处理,无额外成本。

二、环境准备

仅需安装 Excel 解析库(Free Spire.XLS for Python),SQLite 为 Python 内置库,无需额外安装:

复制代码
pip install FreeSpire.XLS

三、核心执行流程

整个程序分为 5 个核心步骤,数据流转清晰无冗余:

加载Excel文件 → 连接数据库 → 遍历工作表 → 读取表头+动态建表 → 逐行数据插入 → 提交事务+释放资源

3.1 完整代码

复制代码
from spire.xls import Workbook
import sqlite3

def excel_to_sqlite(excel_path, db_path):
    # 1. 加载 Excel 文件
    workbook = Workbook()
    workbook.LoadFromFile(excel_path)

    # 2. 连接数据库
    conn = sqlite3.connect(db_path)
    cursor = conn.cursor()

    # 3. 遍历每个工作表
    for sheet_index in range(workbook.Worksheets.Count):
        sheet = workbook.Worksheets.get_Item(sheet_index)
        sheet_name = sheet.Name.replace(" ", "")          # 表名中去掉空格

        # 4. 读取表头(第一行)
        header = []
        for col in range(sheet.AllocatedRange.ColumnCount):
            raw_value = sheet.Range[1, col + 1].Value
            # 字段名中去掉空格,并避免空字段
            field_name = raw_value.replace(" ", "") if raw_value else f"col_{col}"
            header.append(field_name)

        # 5. 创建数据库表(所有字段暂定为 TEXT 类型)
        create_sql = f"""
        CREATE TABLE IF NOT EXISTS {sheet_name} (
            {', '.join([f'[{h}] TEXT' for h in header])}
        )
        """
        cursor.execute(create_sql)

        # 6. 逐行插入数据(跳过表头行)
        for row in range(1, sheet.AllocatedRange.RowCount):  # row=1 对应 Excel 第二行
            row_data = []
            for col in range(sheet.AllocatedRange.ColumnCount):
                cell_value = sheet.Range[row + 1, col + 1].Value
                row_data.append(cell_value)
            
            # 使用参数化查询防止 SQL 注入
            placeholders = ','.join(['?' for _ in row_data])
            insert_sql = f"INSERT INTO {sheet_name} ({','.join(header)}) VALUES ({placeholders})"
            cursor.execute(insert_sql, row_data)

    # 7. 提交并清理
    conn.commit()
    conn.close()
    workbook.Dispose()

if __name__ == "__main__":
    excel_to_sqlite("Sample.xlsx", "output/Report.db")

3.2 关键点解析

1. 工作表遍历与表名清洗
workbook.Worksheets.Count 获取工作表总数,get_Item(s) 按索引获取。工作表名称可能包含空格、特殊字符,直接用作 SQLite 表名会导致语法错误,因此使用 .replace(" ", "") 去除空格。更严谨的做法可增加正则过滤,只保留字母数字和下划线。

2. 动态建表与字段类型

示例将所有字段定义为 TEXT 类型,适配 Excel 中字符串、数字、日期等通用格式(可根据业务修改数据类型)。

3. 数据读取的范围
sheet.AllocatedRange 返回已使用的单元格区域(包含数据的最大矩形),比直接遍历全部行列更高效。注意 RowCountColumnCount 是基于 1 的计数。

4. 参数化插入

使用 ? 占位符配合 cursor.execute(insert_sql, row_data) 能自动处理字符串转义,避免因 Excel 单元格内容包含单引号导致的 SQL 错误,同时防范注入风险。

四、扩展:适配其他数据库

只需修改数据库连接部分,即可迁移到 MySQL、PostgreSQL 等。注意不同数据库的标识符引用符不同(MySQL 用反引号 `````,PostgreSQL 用双引号 "),以及字段类型映射的差异。例如连接 MySQL:

复制代码
import pymysql
conn = pymysql.connect(host='localhost', user='root', password='123456', db='test')
cursor = conn.cursor()
# 建表时将 [field] 改为 `field`
相关推荐
Python大数据分析@2 小时前
使用Python和亮数据采集器搭建专利查询GUI系统
开发语言·python
一个天蝎座 白勺 程序猿2 小时前
Apache IoTDB(16):时序数据库的数据删除从单点精准清除到企业级数据生命周期管理
数据库·apache·时序数据库·iotdb
努力进修2 小时前
【MySQL】90% 的 MySQL 性能问题都和它有关!索引的正确打开方式,看完少走 3 年弯路
数据库·mysql
架构师老Y2 小时前
005、数据库选型与ORM技术:SQLAlchemy深度解析
数据库·python
宝贝儿好2 小时前
【LLM】第一章:分词算法BPE、WordPiece、Unigram、分词工具jieba
人工智能·python·深度学习·神经网络·算法·语言模型·自然语言处理
清水白石0082 小时前
Python 在数据栈中的边界:何时高效原型、何时切换到 SQL、Spark、Rust 或数据库原生能力
数据库·python·自动化
青瓷程序设计2 小时前
基于深度学习的【猫类识别系统】~Python+深度学习+人工智能+算法模型+2026原创+计算机毕设
人工智能·python·深度学习
dishugj2 小时前
sqlplus / as sysdba登录数据库报错ora-01017解决办法
数据库·oracle
好家伙VCC2 小时前
**InfluxDB实战进阶:基于Golang的高性能时序数据采集与可视化方
java·开发语言·后端·python·golang