在C语言中操作Excel表格并将其导入数据库,通常需要借助第三方库来实现,因为标准C语言库本身不直接支持Excel文件的读写和数据库连接,常见的方案包括使用ODBC(开放数据库连接)结合Excel驱动,或者使用专门的Excel操作库如libxlsxwriter、libxls等,再通过数据库API(如MySQL Connector、SQLite3等)将数据存入数据库,以下将详细介绍具体实现步骤和代码示例。
环境准备与依赖安装
-
Excel操作库选择
- 对于.xlsx格式(Excel 2007及以上),推荐使用
libxlsxwriter或OpenXLSX(C++库,可通过C接口调用)。 - 对于.xls格式(Excel 2003及更早),可使用
libxls。 - 示例以
libxlsxwriter为例,需先下载安装:从GitHub获取源码,编译安装sudo make install。
- 对于.xlsx格式(Excel 2007及以上),推荐使用
-
数据库连接库

- 以SQLite3为例(轻量级,无需额外服务),下载
sqlite3.h和libsqlite3.a并配置项目路径。 - 若使用MySQL,需安装
mysql-connector-c。
- 以SQLite3为例(轻量级,无需额外服务),下载
-
ODBC方式(通用方案)
- 配置ODBC数据源:在Windows中通过“ODBC数据源管理器”添加Excel驱动,设置数据源名称(DSN)和Excel文件路径。
- Linux下需安装
unixODBC和odbc-jdbc驱动,并配置odbc.ini。
通过libxlsxwriter读取Excel数据
以下是读取Excel文件并解析数据的代码片段:
#include "xlsxwriter.h"
#include <stdio.h>
void read_excel(const char *filename) {
lxw_workbook *workbook = workbook_open(filename);
lxw_worksheet *worksheet = workbook_get_worksheet_by_name(workbook, "Sheet1");
if (!worksheet) {
printf("Worksheet not found.n");
workbook_close(workbook);
return;
}
int rows = worksheet_get_dim_rows(worksheet);
int cols = worksheet_get_dim_cols(worksheet);
for (int row = 0; row < rows; row++) {
for (int col = 0; col < cols; col++) {
lxw_cell_value *cell = worksheet_read_cell(worksheet, row, col);
if (cell->type == LXW_CELL_TYPE_NUMBER) {
printf("%gt", cell->value.number);
} else if (cell->type == LXW_CELL_TYPE_STRING) {
printf("%st", cell->value.string);
}
}
printf("n");
}
workbook_close(workbook);
}
注意:libxlsxwriter主要用于写入,读取需结合其他库如OpenXLSX或直接解析文件格式(较复杂),实际项目中可考虑调用Python脚本(通过popen)或使用C++库。

通过ODBC读取Excel并导入数据库
以下是ODBC方式读取Excel并插入SQLite3的示例代码:
#include <sql.h>
#include <sqlext.h>
#include <sqlite3.h>
void excel_to_db_via_odbc(const char *excel_path, const char *db_path) {
SQLHENV env;
SQLHDBC dbc;
SQLHSTMT stmt;
// 初始化ODBC环境
SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &env);
SQLSetEnvAttr(env, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0);
SQLAllocHandle(SQL_HANDLE_DBC, env, &dbc);
// 连接Excel数据源(需提前配置DSN)
char conn_str[256];
sprintf(conn_str, "DSN=ExcelDSN;Database=%s", excel_path);
SQLDriverConnect(dbc, NULL, (SQLCHAR*)conn_str, SQL_NTS, NULL, 0, NULL, SQL_DRIVER_COMPLETE);
// 执行查询
SQLAllocHandle(SQL_HANDLE_STMT, dbc, &stmt);
SQLExecDirect(stmt, (SQLCHAR*)"SELECT * FROM [Sheet1$]", SQL_NTS);
// 绑定列(示例:假设两列,第一列字符串,第二列整数)
SQLCHAR col1_data[256];
SQLLEN col1_len;
SQLINTEGER col2_data;
SQLBindCol(stmt, 1, SQL_C_CHAR, col1_data, sizeof(col1_data), &col1_len);
SQLBindCol(stmt, 2, SQL_C_SLONG, &col2_data, 0, NULL);
// 插入SQLite数据库
sqlite3 *db;
sqlite3_open(db_path, &db);
sqlite3_stmt *insert_stmt;
sqlite3_prepare_v2(db, "INSERT INTO excel_data (col1, col2) VALUES (?, ?)", -1, &insert_stmt, NULL);
while (SQLFetch(stmt) == SQL_SUCCESS) {
sqlite3_bind_text(insert_stmt, 1, (const char*)col1_data, -1, SQLITE_STATIC);
sqlite3_bind_int(insert_stmt, 2, col2_data);
sqlite3_step(insert_stmt);
sqlite3_reset(insert_stmt);
}
// 释放资源
SQLFreeHandle(SQL_HANDLE_STMT, stmt);
SQLDisconnect(dbc);
SQLFreeHandle(SQL_HANDLE_DBC, dbc);
SQLFreeHandle(SQL_HANDLE_ENV, env);
sqlite3_finalize(insert_stmt);
sqlite3_close(db);
}
完整流程与注意事项
- 数据映射:Excel列需与数据库表结构匹配,可通过动态SQL或预定义表结构实现。
- 性能优化:批量插入(如SQLite的
exec执行多条语句)可减少IO开销。 - 错误处理:需检查SQL返回值(如
SQLFetch、sqlite3_step)并处理异常。 - 跨平台兼容性:ODBC在Linux下配置较复杂,Windows更简便;纯C方案需处理不同Excel版本的格式差异。
相关问答FAQs
Q1: 如何处理Excel中的日期类型数据?
A: Excel日期存储为数值(如44197代表2020/12/31),读取后需通过mktime或自定义函数转换为Unix时间戳。
time_t excel_date_to_time(double excel_date) {
time_t rawtime = (excel_date - 25569) * 86400; // Excel起始日期为1900/1/1
return rawtime;
}
Q2: 大数据量导入时如何避免内存溢出?
A: 采用分批次读取和插入策略,例如每次读取1000行后执行一次数据库提交,对于SQLite,可设置PRAGMA synchronous=OFF提高写入速度,但需权衡数据安全性。

来源互联网整合,作者:小编,如若转载,请注明出处:https://www.aiboce.com/ask/242634.html