在C语言中导入Excel表格数据到数据库是一个常见的需求,通常涉及Excel文件解析、数据提取以及数据库操作等步骤,以下是详细的实现方法和注意事项,涵盖环境准备、代码实现及异常处理等内容。
环境准备
- 开发工具:推荐使用Visual Studio(Windows)或GCC(Linux),确保支持C99及以上标准。
- 依赖库:
- Excel解析:需安装
libxlsxwriter(用于生成Excel)或libxls/OpenXLS(用于解析旧版.xls),新版.xlsx文件推荐使用xlsxio库。 - 数据库连接:根据数据库类型选择对应的C库,如MySQL用
libmysqlclient、SQLite用sqlite3、PostgreSQL用libpq。 - 其他工具:需安装CMake(用于项目构建)和对应数据库的开发包(如MySQL的
libmysqlclient-dev)。
- Excel解析:需安装
实现步骤
读取Excel文件
以.xlsx文件为例,使用xlsxio库解析数据:
#include <xlsxio/xlsxio.h>
#include <stdio.h>
void read_excel(const char* filename) {
xlsxioreader xlsxioread;
xlsxioread = xlsxioread_open(filename, XLSXIOREAD_SKIP_NONE);
if (!xlsxioread) {
perror("Failed to open Excel file");
return;
}
// 读取第一个工作表
xlsxioreadsheet xlsxioreadsheet = xlsxioread_sheet_open(xlsxioread, NULL, XLSXIOREAD_SKIP_NONE);
if (!xlsxioreadsheet) {
perror("Failed to open sheet");
xlsxioread_close(xlsxioread);
return;
}
// 逐行读取数据
const char* row;
while ((row = xlsxioread_sheet_next_row_string(xlsxioreadsheet)) != NULL) {
printf("%sn", row); // 示例:直接打印行数据
}
xlsxioread_sheet_close(xlsxioreadsheet);
xlsxioread_close(xlsxioread);
}
注意:xlsxio需通过包管理器安装(如Ubuntu的sudo apt install libxlsxio-dev)。

连接数据库
以MySQL为例,使用libmysqlclient:
#include <mysql/mysql.h>
MYSQL* connect_mysql(const char* host, const char* user, const char* password, const char* db) {
MYSQL* mysql = mysql_init(NULL);
if (!mysql) {
perror("MySQL initialization failed");
return NULL;
}
if (!mysql_real_connect(mysql, host, user, password, db, 0, NULL, 0)) {
fprintf(stderr, "Connection error: %sn", mysql_error(mysql));
mysql_close(mysql);
return NULL;
}
return mysql;
}
数据导入与处理
将Excel数据解析后插入数据库,需注意数据类型转换和SQL注入防护:

void import_data_to_mysql(MYSQL* mysql, const char* excel_file) {
xlsxioreader xlsxioread = xlsxioread_open(excel_file, XLSXIOREAD_SKIP_NONE);
xlsxioreadsheet xlsxioreadsheet = xlsxioread_sheet_open(xlsxioread, NULL, XLSXIOREAD_SKIP_NONE);
const char* row;
while ((row = xlsxioread_sheet_next_row_string(xlsxioreadsheet)) != NULL) {
// 假设Excel每行包含三列:ID, Name, Age
int id, age;
char name[50];
if (sscanf(row, "%d,%49[^,],%d", &id, name, &age) != 3) {
fprintf(stderr, "Invalid row format: %sn", row);
continue;
}
// 使用预处理语句防止SQL注入
MYSQL_STMT* stmt = mysql_stmt_init(mysql);
const char* query = "INSERT INTO users (id, name, age) VALUES (?, ?, ?)";
if (mysql_stmt_prepare(stmt, query, strlen(query)) != 0) {
fprintf(stderr, "Prepare failed: %sn", mysql_stmt_error(stmt));
mysql_stmt_close(stmt);
continue;
}
// 绑定参数
int id_param = id;
char name_param[50];
strcpy(name_param, name);
int age_param = age;
MYSQL_BIND bind[3];
memset(bind, 0, sizeof(bind));
bind[0].buffer_type = MYSQL_TYPE_LONG;
bind[0].buffer = &id_param;
bind[1].buffer_type = MYSQL_TYPE_STRING;
bind[1].buffer = name_param;
bind[1].buffer_length = strlen(name_param);
bind[2].buffer_type = MYSQL_TYPE_LONG;
bind[2].buffer = &age_param;
if (mysql_stmt_bind_param(stmt, bind) != 0) {
fprintf(stderr, "Bind failed: %sn", mysql_stmt_error(stmt));
mysql_stmt_close(stmt);
continue;
}
if (mysql_stmt_execute(stmt) != 0) {
fprintf(stderr, "Execute failed: %sn", mysql_stmt_error(stmt));
}
mysql_stmt_close(stmt);
}
xlsxioread_sheet_close(xlsxioreadsheet);
xlsxioread_close(xlsxioread);
}
主函数整合
int main() {
// 1. 连接MySQL
MYSQL* mysql = connect_mysql("localhost", "root", "password", "test_db");
if (!mysql) return 1;
// 2. 读取Excel并导入
import_data_to_mysql(mysql, "data.xlsx");
// 3. 关闭连接
mysql_close(mysql);
return 0;
}
常见问题与解决方案
- Excel文件格式不支持:确保使用支持
.xlsx的库(如xlsxio),旧版.xls需用libxls。 - 数据库连接失败:检查主机地址、用户名、密码及数据库是否运行,并确认网络连通性。
- 数据类型不匹配:使用
sscanf或strtol等函数转换数据类型,或通过MYSQL_BIND指定数据库字段类型。 - 内存泄漏:确保关闭所有打开的句柄(如
xlsxioread_close、mysql_stmt_close)。
性能优化建议
- 批量插入:使用
mysql_stmt_execute批量提交数据,减少网络开销。 - 事务处理:通过
mysql_commit和mysql_rollback确保数据一致性。 - 多线程处理:对大型Excel文件,可分片读取并多线程导入(需注意线程安全)。
相关问答FAQs
Q1: 如何处理Excel中的日期格式数据?
A1: Excel日期存储为数值(如44197表示2020-12-31),需转换为YYYY-MM-DD格式,使用mktime或自定义函数将Excel日期戳转换为Unix时间戳,再格式化为字符串插入数据库。
Q2: 导入时如何跳过Excel表头?
A2: 在xlsxio中,通过XLSXIOREAD_SKIP_HEADER标志跳过首行:

xlsxioread = xlsxioread_open(filename, XLSXIOREAD_SKIP_HEADER);
或在循环中计数,跳过第一行(如if (row_count++ == 0) continue;)。
来源互联网整合,作者:小编,如若转载,请注明出处:https://www.aiboce.com/ask/242642.html