要在C语言中读取Excel数据并将其存储在数组中,可以使用以下步骤:
1. 包含必要的头文件和库:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include <errno.h>
#include <windows.h>
#include <ole2.h>
#include <olectl.h>
#include <ocidl.h>
```
2. 使用COM接口打开Excel文件,并获取工作簿和工作表对象:
```c
// 打开Excel文件
CoInitialize(NULL);
IDispatch* pXLApp = NULL;
CLSID clsid;
CLSIDFromProgID(L"Excel.Application", &clsid);
HRESULT hr = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER, IID_IDispatch, (void**)&pXLApp);
if (FAILED(hr)) {
printf("Failed to create Excel instance.\n");
return 1;
}
// 打开工作簿
VARIANT varFileName;
VariantInit(&varFileName);
varFileName.vt = VT_BSTR;
varFileName.bstrVal = SysAllocString(L"example.xlsx"); // Excel文件名
IDispatch* pWorkbooks = NULL;
hr = pXLApp->GetIDispatch(L"Workbooks", (void**)&pWorkbooks);
if (FAILED(hr)) {
printf("Failed to get Workbooks object.\n");
return 1;
}
IDispatch* pWorkbook = NULL;
hr = pWorkbooks->Invoke(0x3ec, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispparamsNoArgs, &varResult, NULL, NULL);
if (FAILED(hr)) {
printf("Failed to get item(1) of Workbooks object.\n");
return 1;
}
// 获取工作表对象
VARIANT varWorksheetName;
VariantInit(&varWorksheetName);
varWorksheetName.vt = VT_BSTR;
varWorksheetName.bstrVal = SysAllocString(L"Sheet1"); // 工作表名
IDispatch* pWorksheets = NULL;
hr = pWorkbook->GetIDispatch(L"Worksheets", (void**)&pWorksheets);
if (FAILED(hr)) {
printf("Failed to get Worksheets object.\n");
return 1;
}
IDispatch* pWorksheet = NULL;
hr = pWorksheets->Invoke(0x74, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispparamsNoArgs, &varResult, NULL, NULL);
if (FAILED(hr)) {
printf("Failed to get Item() of Worksheets object.\n");
return 1;
}
```
3. 获取Excel数据的范围,并确定数组的大小:
```c
// 获取数据范围
VARIANT varRangeName;
VariantInit(&varRangeName);
varRangeName.vt = VT_BSTR;
varRangeName.bstrVal = SysAllocString(L"A1:C10"); // 数据范围
IDispatch* pRange = NULL;
hr = pWorksheet->GetIDsOfNames(IID_NULL, &varRangeName.bstrVal, 1, LOCALE_USER_DEFAULT, &dispid);
if (FAILED(hr)) {
printf("Failed to get IDs of names.\n");
return 1;
}
hr = pWorksheet->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispparamsNoArgs, &varResult, NULL, NULL);
if (FAILED(hr)) {
printf("Failed to get Range object.\n");
return 1;
}
pRange = varResult.pdispVal;
// 获取数据大小
long numRows = 0;
long numCols = 0;
hr = pRange->GetIDsOfNames(IID_NULL, &dispidNumRows, 1, LOCALE_USER_DEFAULT, &dispid);
if (FAILED(hr)) {
printf("Failed to get IDs of names.\n");
return 1;
}
hr = pRange->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispparamsNoArgs, &varResult, NULL, NULL);
if (FAILED(hr)) {
printf("Failed to get number of rows.\n");
return 1;
}
numRows = varResult.lVal;
hr = pRange->GetIDsOfNames(IID_NULL, &dispidNumCols, 1, LOCALE_USER_DEFAULT, &dispid);
if (FAILED(hr)) {
printf("Failed to get IDs of names.\n");
return 1;
}
hr = pRange->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispparamsNoArgs, &varResult, NULL, NULL);
if (FAILED(hr)) {
printf("Failed to get number of columns.\n");
return 1;
}
numCols = varResult.lVal;
// 确定数组大小
int numRowsInt = (int)numRows;
int numColsInt = (int)numCols;
double** pData = (double**)malloc(numRowsInt * sizeof(double*));
for (int i = 0; i < numRowsInt; i++) {
pData[i] = (double*)malloc(numColsInt * sizeof(double));
}
```
4. 读取数据并存储在数组中:
```c
// 读取数据
for (int i = 1; i <= numRowsInt; i++) {
for (int j = 1; j <= numColsInt; j++) {
VARIANT varValue;
VariantInit(&varValue);
IDispatch* pCell = NULL;
hr = pRange->GetIDsOfNames(IID_NULL, &dispidItem, 1, LOCALE_USER_DEFAULT, &dispid);
if (FAILED(hr)) {
printf("Failed to get IDs of names.\n");
return 1;
}
VARIANTARG vargIndex;
VariantInit(&vargIndex);
vargIndex.vt = VT_I4;
vargIndex.lVal = i * pow(2, 16) + j;
dispparams.rgvarg = &vargIndex;
dispparams.cArgs = 1;
hr = pRange->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispparams, &varResult, NULL, NULL);
if (FAILED(hr)) {
printf("Failed to get cell.\n");
return 1;
}
pCell = varResult.pdispVal;
hr = pCell->GetIDsOfNames(IID_NULL, &dispidValue, 1, LOCALE_USER_DEFAULT, &dispid);
if (FAILED(hr)) {
printf("Failed to get IDs of names.\n");
return 1;
}
hr = pCell->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispparamsNoArgs, &varValue, NULL, NULL);
if (FAILED(hr)) {
printf("Failed to get cell value.\n");
return 1;
}
pData[i - 1][j - 1] = varValue.dblVal;
}
}
```
5. 关闭Excel文件和COM接口:
```c
// 关闭对象
pRange->Release();
pWorksheet->Release();
pWorksheets->Release();
pWorkbook->Release();
pWorkbooks->Release();
pXLApp->Release();
// 释放内存
for (int i = 0; i < numRowsInt; i++) {
free(pData[i]);
}
free(pData);
// 关闭COM接口
CoUninitialize();
```
完整的代码如下所示:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include <errno.h>
#include <windows.h>
#include <ole2.h>
#include <olectl.h>
#include <ocidl.h>
int main()
{
// 打开Excel文件
CoInitialize(NULL);
IDispatch* pXLApp = NULL;
CLSID clsid;
CLSIDFromProgID(L"Excel.Application", &clsid);
HRESULT hr = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER, IID_IDispatch, (void**)&pXLApp);
if (FAILED(hr)) {
printf("Failed to create Excel instance.\n");
return 1;
}
// 打开工作簿
VARIANT varFileName;
VariantInit(&varFileName);
varFileName.vt = VT_BSTR;
varFileName.bstrVal = SysAllocString(L"example.xlsx"); // Excel文件名
DISPPARAMS dispparamsNoArgs = { NULL, NULL, 0, 0 };
VARIANT varResult;
IDispatch* pWorkbooks = NULL;
hr = pXLApp->GetIDispatch(L"Workbooks", (void**)&pWorkbooks);
if (FAILED(hr)) {
printf("Failed to get Workbooks object.\n");
return 1;
}
DISPID dispid = 0;
hr = pWorkbooks->GetIDsOfNames(IID_NULL, &L"Open", 1, LOCALE_USER_DEFAULT, &dispid);
if (FAILED(hr)) {
printf("Failed to get IDs of names.\n");
return 1;
}
VARIANTARG dispparamsOpen[4];
dispparamsOpen[3].vt = VT_BOOL;
dispparamsOpen[3].boolVal = FALSE;
dispparamsOpen[2].vt = VT_BOOL;
dispparamsOpen[2].boolVal = FALSE;
dispparamsOpen[1].vt = VT_BOOL;
dispparamsOpen[1].boolVal = FALSE;
dispparamsOpen[0].vt = VT_BSTR;
dispparamsOpen[0].bstrVal = varFileName.bstrVal;
dispparams.cArgs = 4;
dispparams.rgvarg = dispparamsOpen;
hr = pWorkbooks->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispparams, &varResult, NULL, NULL);
if (FAILED(hr)) {
printf("Failed to open workbook.\n");
return 1;
}
IDispatch* pWorkbook = NULL;
hr = pWorkbooks->Invoke(0x3ec, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispparamsNoArgs, &varResult, NULL, NULL);
if (FAILED(hr)) {
printf("Failed to get item(1) of Workbooks object.\n");
return 1;
}
pWorkbook = varResult.pdispVal;
// 获取工作表对象
VARIANT varWorksheetName;
VariantInit(&varWorksheetName);
varWorksheetName.vt = VT_BSTR;
varWorksheetName.bstrVal = SysAllocString(L"Sheet1"); // 工作表名
IDispatch* pWorksheets = NULL;
hr = pWorkbook->GetIDispatch(L"Worksheets", (void**)&pWorksheets);
if (FAILED(hr)) {
printf("Failed to get Worksheets object.\n");
return 1;
}
IDispatch* pWorksheet = NULL;
hr = pWorksheets->Invoke(0x74, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispparamsNoArgs, &varResult, NULL, NULL);
if (FAILED(hr)) {
printf("Failed to get Item() of Worksheets object.\n");
return 1;
}
// 获取数据范围
VARIANT varRangeName;
VariantInit(&varRangeName);
varRangeName.vt = VT_BSTR;
varRangeName.bstrVal = SysAllocString(L"A1:C10"); // 数据范围
DISPID dispidNumRows = 0;
DISPID dispidNumCols = 0;
DISPID dispidItem = 0;
DISPID dispidValue = 0;
IDispatch* pRange = NULL;
hr = pWorksheet->GetIDsOfNames(IID_NULL, &varRangeName.bstrVal, 1, LOCALE_USER_DEFAULT, &dispid);
if (FAILED(hr)) {
printf("Failed to get IDs of names.\n");
return 1;
}
hr = pWorksheet->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispparamsNoArgs, &varResult, NULL, NULL);
if (FAILED(hr)) {
printf("Failed to get Range object.\n");
return 1;
}
pRange = varResult.pdispVal;
// 获取数据大小
long numRows = 0;
long numCols = 0;
hr = pRange->GetIDsOfNames(IID_NULL, &L"Rows", 1, LOCALE_USER_DEFAULT, &dispidNumRows);
if (FAILED(hr)) {
printf("Failed to get IDs of names.\n");
return 1;
}
hr = pRange->Invoke(dispidNumRows, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispparamsNoArgs, &varResult, NULL, NULL);
if (FAILED(hr)) {
printf("Failed to get number of rows.\n");
return 1;
}
numRows = varResult.lVal;
hr = pRange->GetIDsOfNames(IID_NULL, &L"Columns", 1, LOCALE_USER_DEFAULT, &dispidNumCols);
if (FAILED(hr)) {
printf("Failed to get IDs of names.\n");
return 1;
}
hr = pRange->Invoke(dispidNumCols, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispparamsNoArgs, &varResult, NULL, NULL);
if (FAILED(hr)) {
printf("Failed to get number of columns.\n");
return 1;
}
numCols = varResult.lVal;
// 确定数组大小
int numRowsInt = (int)numRows;
int numColsInt = (int)numCols;
double** pData = (double**)malloc(numRowsInt * sizeof(double*));
for (int i = 0; i < numRowsInt; i++) {
pData[i] = (double*)malloc(numColsInt * sizeof(double));
}
// 读取数据
for (int i = 1; i <= numRowsInt; i++) {
for (int j = 1; j <= numColsInt; j++) {
VARIANT varValue;
VariantInit(&varValue);
IDispatch* pCell = NULL;
hr = pRange->GetIDsOfNames(IID_NULL, &L"Item", 1, LOCALE_USER_DEFAULT, &dispid);
if (FAILED(hr)) {
printf("Failed to get IDs of names.\n");
return 1;
}
VARIANTARG dispparamsItem[1];
dispparamsItem[0].vt = VT_I4;
dispparamsItem[0].lVal = i * pow(2, 16) + j;
DISPPARAMS dispparams = { dispparamsItem, NULL, 1, 0 };
hr = pRange->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispparams, &varResult, NULL, NULL);
if (FAILED(hr)) {
printf("Failed to get cell.\n");
return 1;
}
pCell = varResult.pdispVal;
hr = pCell->GetIDsOfNames(IID_NULL, &L"Value", 1, LOCALE_USER_DEFAULT, &dispidValue);
if (FAILED(hr)) {
printf("Failed to get IDs of names.\n");
return 1;
}
hr = pCell->Invoke(dispidValue, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispparamsNoArgs, &varValue, NULL, NULL);
if (FAILED(hr)) {
printf("Failed to get cell value.\n");
return 1;
}
pData[i - 1][j - 1] = varValue.dblVal;
}
}
// 关闭对象
pRange->Release();
pWorksheet->Release();
pWorksheets->Release();
pWorkbook->Release();
pWorkbooks->Release();
pXLApp->Release();
// 释放内存
for (int i = 0; i < numRowsInt; i++) {
free(pData[i]);
}
free(pData);
// 关闭COM接口
CoUninitialize();
return 0;
}
```