最近用到excel导入数据库的问题,网上查阅资料之后整理出相对独立的一个版本,以便于以后使用。
这里创建一个基于VS2005的控制台应用程序,字符集设置为“未设置”,经测试可以通过,有关ADO操作Excel的细节问题,可参阅相关资料。
// readExcel.cpp : 定义控制台应用程序的入口点。
//
#include <string.h>
#include <list>
#include <stdio.h>
#include <tchar.h>
using namespace std;
#import "C:\Program Files\Common Files\System\ado\msado15.dll" rename("EOF", "adoEOF")
using namespace ADODB;
#pragma warning(disable:4996)
struct Person
{
char Number[12]; //手机号
char Name[32]; //姓名
};
int GetDataFromExcel(const char *sFilePath, list<Person> &outPersonList);
int _tmain(int argc, _TCHAR* argv[])
{
::CoInitialize(NULL); //初始化COM组件
char szFilePath[] = "D:\\test.xls";
list<Person> personList;
int result = GetDataFromExcel(szFilePath, personList);
switch (result)
{
case 0:
{
printf("Open File Success!\n");
list<Person>::iterator it;
for (it=personList.begin(); it!=personList.end(); it++)
{
printf("Number:%12s Name:%s\n", (*it).Number, (*it).Name);
}
}
break;
case 1:
printf("File Not Fount!\n");
break;
case 2:
printf("File Format Wrong!\n");
break;
case -1:
printf("Database Failed!\n");
break;
default:
break;
}
::CoUninitialize(); //卸载COM组件
return 0;
}
//将xls表中的数据读取到Person链表中
//输入:const char *sFilePath excel文件路径
//输出:list<Person> &outPersonList 查询结果按照PhoneMap对象的格式封装成链表
// 读取执行结果 0,成功;1,excel文件不存在;2,excel文件格式不正确;-1,数据库操作失败
//描述:excel文件格式在这里是指第一行是“手机号”,第二行是“姓名”
int GetDataFromExcel(const char *sFilePath, list<Person> &outPersonList)
{
// 1. 清空输出链表
outPersonList.clear();
// 2. 查询excel文件是否存在
WIN32_FIND_DATA findFileData;
HANDLE hFind = FindFirstFile(sFilePath, &findFileData);
if (hFind == INVALID_HANDLE_VALUE)
{
return 1;
}
FindClose(hFind);
// 3. 连接excel数据库
_ConnectionPtr connection;
char szConnStr[256];
/*"HDR=Yes;" 表示工作表的第一行是表头,没有数据。 "HDR=No;"与之相反。
"IMEX=1;"告诉驱动程序始终将"intermixed"数据类型(numbers, dates, strings等等)作为文本型读取。
注意:该选项可能引起Excel工作表写权限的修改。如果想写入数据,创建新表等必须使其为0*/
sprintf(szConnStr, "Provider=Microsoft.Ace.OLEDB.12.0;Data Source=%s; "
"Extended Properties=\"Excel 8.0;HDR=Yes;IMEX=1\"", sFilePath);
try
{
connection.CreateInstance(__uuidof(Connection)); //创建Connection对象
connection->Open(_bstr_t(szConnStr), "", "", adModeUnknown);
}
catch (_com_error e)
{
return -1;
}
// 4. 获取记录集
_RecordsetPtr pRecordset;
char szSQL[] = "Select * From [Sheet1$]";
try
{
pRecordset.CreateInstance(__uuidof(Recordset)); //创建Recordset对象
pRecordset->Open(_bstr_t(szSQL), _variant_t((IDispatch*)connection, TRUE),
adOpenUnspecified, adLockUnspecified, adCmdUnknown);
}
catch (_com_error e)
{
connection->Close();
return -1;
}
if (pRecordset == NULL)
{
connection->Close();
return -1;
}
// 5. 提取数据
int result = 0;
if (!pRecordset->BOF)
{
try
{
pRecordset->MoveFirst();
while (!pRecordset->adoEOF)
{
Person person;
_variant_t vtPhoneNumber = pRecordset->Fields->GetItem("手机号")->Value;
_variant_t vtClient = pRecordset->Fields->GetItem("姓名")->Value;
if (vtPhoneNumber.vt == VT_R8 && vtClient.vt == VT_BSTR)
{
sprintf(person.Number, "%011.0lf", vtPhoneNumber.dblVal);
WideCharToMultiByte(CP_ACP, 0, vtClient.bstrVal, -1,
person.Name, sizeof(person.Name), NULL, NULL);
outPersonList.push_back( person );
}
pRecordset->MoveNext();
}
}
catch (_com_error e)
{
result = 2;
}
}
// 6. 关闭数据库连接对象、记录集对象
pRecordset->Close();
connection->Close();
return 0;
}