libxls 与 数据库

什么excel什么表格我表示一概不懂,最近刚好在看数据库方面的知识,我在想如果把excel文件里面的内容导入到mysql中用起来该是多么的方便,(当然这只是在我不懂excel前提下的一厢情愿),再加上我也要找个数据库练练手,手里还有两个excel文件,于是乎就想到了将excel文件中的内容导入到mysql数据库中。
我并不知道有没有其它的什么方法,因为我压根就没去搜索过,我的方法只有一个,那就是找个能读出excel文件内容的c语言接口,然后再通过mysql提供的c语言接口写个程序将excel文件内容导入到数据库中。

读取excel文件的库我使用的是libxls,这个可以在http://libxls.sourceforge.net/ 下载到,选择相应的平台,比如我用的linux我直接下载了源码编译,如果你是windows,就选择for windows的那个包下载,sourceforge.net听说内地访问不了,据说是sourceforge.net屏蔽了内地的ip地址,所以如果你访问不了的话,就想其它办法吧,或者可以去去其它的地方搜索下libxls的源码,比如github或者开源中国什么的,至于这里有没有我没考证了,科学上网是你应该懂的一项技能

对libxls的使用我也不熟悉,只是在网上找了点资料,只要读出了excel文件的内容也就足够了,mysql的接口也是如此,这里先说下几个函数和数据结构

xlsWorkBook *pWb;

xlsWorkSheet *pWs;
struct st_row_data *row;

打开一个excel表格

 pWb = xls_open(argv[1], "UTF-8");

读取表格的第1页

pWs = xls_getWorkSheet(pWb, 0);
xls_parseWorkSheet(pWs);

获取一行(r)的内容

row = &pWs->rows.row[r];

得到某一列的文本

row->cells.cell[3].str

关闭

xls_close_WS(pWs);
xls_close_WB(pWb);

至于mysql这里只是插入一个操作,所以一个mysql_query足够了
但是在使用mysql之前还需要初始化数据结构和对数据库进行连接

初始化
mysql=mysql_init(NULL);
如果初始化出错则返回NULL

连接数据库服务器
mysql_real_connect(mysql,"127.0.0.1",user,passwd,database,3306,NULL,0);
user是你登陆mysql服务器所使用的名字
passwd是对应的密码
database是你要选择的操作的数据库名称
3306是mysql服务器的端口,如果你对mysql的端口做过更改的话填上相应的端口

做实验的excel文件各例是下面这些内容
日期  姓名  性别  身份证号码   家庭住址   电话
我们假如就是这些吧

由于我手中的excel文件中有一个日期数据类型(不知道该不该这样说),这种数据读出来后不是以YY-MM-DD的方式显示出来的,而是一个浮点数,所以得想办法将这个浮点数转换为相应的日期,经过搜索,发现这个浮点数的整数部分是自1900年以来到相应日期的天数,小数部分为时间,由于我这里的excel文件是YY-MM-DD格式的,所以只有年月日,没有时分钞,也就是说小数年部分是0,所以对小数部分不作研究了,现在就是要计算出整数部分然后再转换为YY-DD-MM这种格式,有了上面的算法就好办了,这里找一个数据做说明

41425.000000
我们取整数部分也就是41425
我们推算出1900年1月1日后41425天后应该是什么日子
这里要注意的当然是闰年和平年的问题了,经过计算应该是2013年5月31日,怎么计算的,下面的代码中会有计算的环节,不过我们还是先创建一个空表

create table 人员名单(日期 date not null,姓名 varchar(12) not null,身份证号码 char(18) not null,家庭住址 varchar(100) not null,电话 char(11) null);

下面是读取excel文件并写入数据库的代码

#include <mysql/mysql.h>
#include <xls.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct
{
    int year;
    int mon;
    int day;
}DATE;  //对excel日期格式转换所使用的数据类型

#define _quit(msg) \
{\
    error_quit(msg,mysql);\
}

void error_quit(char *msg,MYSQL *mysql)
{
    printf("%s:%s\n",mysql_error(mysql));
    exit(-1);
}

void help(void)
{
    printf("Use:\n");
    printf("insert_xls_to_mysql host username passwd database port xls\n");
    exit(-2);
}

int leap_year(int year)
{
    if((year%4 == 0 && year%100 != 0) || year%400 == 0)
        return 1;
    else
        return 0;
} //计算闰年平年

void get_year_and_day(DATE *date,int day)
{
    int year,d;

    for(year=1900,d=0;day-d >= 0;++year)
    {
        if(leap_year(year))
            d+=366;
        else
            d+=365;
    }

    if(leap_year(year-1))
        d-=366;
    else
        d-=365;

    date->year=year-1;
    if(day-d == 0)
        date->day=0;
    else
        date->day=day-d-1;
}  //填充DATE中的year和day,计算出自1900年后的XXX天是多少年,此时day内为具体日期为该年的第多少天

void get_date(DATE *date,int day)
{
    int i,j;
    int d[12]={31,28,31,30,31,30,31,31,30,31,30,31};

    get_year_and_day(date,day);

    if(leap_year(date->year))
        d[1]=29;

    for(i=0,j=0;date->day-j > 0;++i)
        j+=d[i];

    date->mon=i;
    date->day=d[i-1]-j+date->day;
}  //填充DATE中的所有数据,得到自1900年XXX天后为某年某月某日

void insert_to_mysql(int col,struct st_row_data *row,MYSQL *mysql)
{
    int i;
    char insert[1024]={0};
    char temp[1024]={0};
    DATE date;
    char d[20]={0};

    for(i=0;row->cells.cell[0].str[i];++i)
    {
        if(row->cells.cell[0].str[i] == '.')
            break;

        d[i]=row->cells.cell[0].str[i];
    }  //日期在第一列,取出整数部分进行转换
    
    get_date(&date,atoi(d));
    bzero(d,sizeof(d));
    sprintf(d,"\"%d-%d-%d\"",date.year,date.mon,date.day);  

    for(i=1;i < col;++i)
    {
        if(row->cells.cell[i].str != NULL)
        {
            strcat(temp,"\"");
            strcat(temp,row->cells.cell[i].str);
            strcat(temp,"\"");
        }
        else
            strcat(temp,"null");

        strcat(temp,",");
    } 

    i=strlen(temp);
    temp[i-1]='\0';

    sprintf(insert,"insert 人员名单 values(%s,%s)",d,temp); //封装sql插入语句,这里注意字符串类型数据要加上"
    printf("%s\n",insert);
    if(mysql_query(mysql,insert) != 0)
        printf("%s\n",mysql_error(mysql));
    //free(date);
}

int main(int argc,char **argv)
{
    MYSQL *mysql;
    xlsWorkBook *wb;
    xlsWorkSheet *ws;
    struct st_row_data *row;
    int xls_i;
    
    if(argc != 7)
        help();

    if((mysql=mysql_init(NULL)) == NULL)
        _quit("Init Mysql Error!");
    if(mysql_real_connect(mysql,argv[1],argv[2],argv[3],
                argv[4],atoi(argv[5]),NULL,0) == NULL)
        _quit("Connect To Mysql Error!");
    mysql_query(mysql,"set names utf8");

    wb=xls_open(argv[6],"UTF-8");
    ws=xls_getWorkSheet(wb,0); //我的excel文件只有一页,所以只打开一页
    xls_parseWorkSheet(ws); //打开并解析一个excel文件

    for(xls_i=4;xls_i <= ws->rows.lastrow;++xls_i)  //从第四行开始,因为前四行为一些说明内容包括列名称,这里根据自己情况作改变
    {
        row=&ws->rows.row[xls_i];
        insert_to_mysql(ws->rows.lastcol,row,mysql);
    }

    xls_close_WS(ws);
    xls_close_WB(wb);
    mysql_close(mysql);

    return 0;

}

编译使用gcc
gcc -o insert_xls_to_mysql insert_xls_to_mysql.c -lxlsreader -lmysqlclient

./insert_xls_to_mysql 127.0.0.1 username passwd database 3306 人员名单.xls

现在可以去看看是不是已经将内容导入到数据库中去了
select * from 人员名单;
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值