如何通过 ADO 在 C++ 中读写 Excel 文件






4.85/5 (21投票s)
使用 ADO 在 C++ 中访问 XLS 和 XLSX 文件。
引言
有时软件开发者需要将一些数据导出到 Excel 格式,或者从 Excel 文件中读取一些单元格。 一种无需 Excel 自动化即可实现的方法是与 ADO 交互。在这种情况下,Excel 文件被视为数据库。 这种方法不需要 Microsoft Excel 并且速度足够快,但它不支持格式和公式。
连接字符串
有两种类型的连接字符串。 第一个是二进制格式 (xls)
Provider=Microsoft.JET.OLEDB.4.0;Data Source=data.xls;Extended Properties="Excel 8.0"
第二个是 XML 格式 (xlsx)
Provider=Microsoft.ACE.OLEDB.12.0;Data Source=data.xlsx;
Extended Properties="Excel 12.0 Xml"
如果输入文件没有包含列名的标题,则在扩展属性中添加 ";HDR=NO
"。
写入
首先创建一个 Connection
对象
TESTHR(pCon.CreateInstance(__uuidof(Connection)));
TESTHR(pCon->Open(connStr, "", "", NULL));
之后,创建 Command
对象和表。 请注意,表名是工作表的名称
TESTHR(pCmd.CreateInstance(__uuidof(Command)));
pCmd->ActiveConnection = pCon;
pCmd->CommandText = "CREATE TABLE MySheet
(A int, B varchar, C int, D int, E int, F int, G int, H int, I int, J varchar)";
pCmd->Execute(NULL, NULL, adCmdText);
创建 Recordset
并添加带有值的记录
TESTHR(pRec.CreateInstance(__uuidof(Recordset)));
pRec->Open("SELECT * FROM MySheet", _variant_t((IDispatch*)pCon),
adOpenKeyset, adLockOptimistic, adCmdText);
for(int i = 0; i < writeRows; ++i)
{
TESTHR(pRec->AddNew());
char str[11] = {0}; for(int j = 0; j < 10; ++j) str[j] = 'a' + (rand() % 26);
pRec->Fields->GetItem("A")->Value = _variant_t(i);
pRec->Fields->GetItem("B")->Value = _variant_t(str);
pRec->Fields->GetItem("C")->Value = _variant_t(i);
pRec->Fields->GetItem("D")->Value = _variant_t(i);
pRec->Fields->GetItem("E")->Value = _variant_t(i);
pRec->Fields->GetItem("F")->Value = _variant_t(i);
pRec->Fields->GetItem("G")->Value = _variant_t(i);
pRec->Fields->GetItem("H")->Value = _variant_t(i);
pRec->Fields->GetItem("I")->Value = _variant_t(i);
pRec->Fields->GetItem("J")->Value = _variant_t(str);
}
TESTHR(pRec->Update());
TESTHR(pRec->Close());
读取
创建并打开 Recordset
TESTHR(pRec.CreateInstance(__uuidof(Recordset)));
TESTHR(pRec->Open("SELECT * FROM [Sheet1$]", connStr,
adOpenStatic, adLockOptimistic, adCmdText));
如果工作表的名称未知,则可以通过索引查找它
TESTHR(pCon.CreateInstance(__uuidof(Connection)));
TESTHR(pCon->Open(connStr, "", "", NULL));
pSchema = pCon->OpenSchema(adSchemaTables);
for(int i = 0; i < sheetIndex; ++i) pSchema->MoveNext();
std::string sheetName =
(char*)(_bstr_t)pSchema->Fields->GetItem("TABLE_NAME")->Value.bstrVal;
提取单元格的值
while(!pRec->adoEOF)
{
for(long i = 0; i < pRec->Fields->GetCount(); ++i)
{
if(i > 0) stream << ";";
_variant_t v = pRec->Fields->GetItem(i)->Value;
if(v.vt == VT_R8)
stream << v.dblVal;
if(v.vt == VT_BSTR)
stream << (char*)(_bstr_t)v.bstrVal;
}
stream << std::endl;
pRec->MoveNext();
}
历史
- 2010 年 11 月 10 日:初始发布