C语言 vs2022 Win32API COM 读取 Excel 表格的工具类可以运行的代码
时间: 2023-11-28 09:50:37 浏览: 182
表格类.源代码,可运行
5星 · 资源好评率100%
以下是一个示例代码,它演示了如何使用C语言和Win32API读取Excel表格数据。这个示例使用COM接口来访问Excel应用程序。请注意,您需要安装Microsoft Office(包括Excel)才能运行此代码。
```c
#include <Windows.h>
#include <stdio.h>
#include <conio.h>
// Excel应用程序对象指针
IDispatch* pExcelApp = NULL;
// Excel工作簿对象指针
IDispatch* pWorkbook = NULL;
// Excel工作表对象指针
IDispatch* pWorksheet = NULL;
// 打开Excel应用程序
BOOL OpenExcel()
{
// 初始化COM库
CoInitialize(NULL);
// 创建Excel应用程序对象
CLSID clsid;
HRESULT hr = CLSIDFromProgID(L"Excel.Application", &clsid);
if (FAILED(hr))
{
printf("Could not create Excel application object.\n");
return FALSE;
}
hr = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER, IID_IDispatch, (void**)&pExcelApp);
if (FAILED(hr))
{
printf("Could not create Excel application object.\n");
return FALSE;
}
// 设置Excel应用程序为可见
VARIANT vis;
vis.vt = VT_BOOL;
vis.boolVal = TRUE;
hr = SetProperty(pExcelApp, L"Visible", &vis);
if (FAILED(hr))
{
printf("Could not set Visible property of Excel application object.\n");
return FALSE;
}
return TRUE;
}
// 打开Excel工作簿
BOOL OpenWorkbook(const char* filename)
{
if (!pExcelApp)
return FALSE;
// 打开工作簿
VARIANT vFilename;
vFilename.vt = VT_BSTR;
vFilename.bstrVal = SysAllocStringLen(NULL, strlen(filename));
MultiByteToWideChar(CP_ACP, 0, filename, -1, vFilename.bstrVal, strlen(filename));
VARIANT vUpdateLinks;
vUpdateLinks.vt = VT_BOOL;
vUpdateLinks.boolVal = FALSE;
VARIANT vReadOnly;
vReadOnly.vt = VT_BOOL;
vReadOnly.boolVal = TRUE;
VARIANT vFormat;
vFormat.vt = VT_BOOL;
vFormat.boolVal = FALSE;
VARIANT vPassword;
vPassword.vt = VT_BSTR;
vPassword.bstrVal = NULL;
VARIANT vWriteResPassword;
vWriteResPassword.vt = VT_BSTR;
vWriteResPassword.bstrVal = NULL;
VARIANT vIgnoreReadOnlyRecommended;
vIgnoreReadOnlyRecommended.vt = VT_BOOL;
vIgnoreReadOnlyRecommended.boolVal = FALSE;
VARIANT vOrigin;
vOrigin.vt = VT_DISPATCH;
vOrigin.pdispVal = NULL;
VARIANT vDelimiter;
vDelimiter.vt = VT_BSTR;
vDelimiter.bstrVal = NULL;
VARIANT vEditable;
vEditable.vt = VT_BOOL;
vEditable.boolVal = FALSE;
VARIANT vNotify;
vNotify.vt = VT_BOOL;
vNotify.boolVal = FALSE;
VARIANT vConverter;
vConverter.vt = VT_I4;
vConverter.lVal = 0;
VARIANT vResult;
VariantInit(&vResult);
DISPID dispid;
HRESULT hr = GetPropertyID(pExcelApp, L"Workbooks", &dispid);
if (FAILED(hr))
{
printf("Could not get Workbooks property ID.\n");
return FALSE;
}
hr = InvokeMethod(pExcelApp, dispid, DISPATCH_PROPERTYGET, &vResult, 0);
if (FAILED(hr))
{
printf("Could not get Workbooks collection.\n");
return FALSE;
}
IDispatch* pWorkbooks = vResult.pdispVal;
hr = GetPropertyID(pWorkbooks, L"Open", &dispid);
if (FAILED(hr))
{
printf("Could not get Open method ID.\n");
return FALSE;
}
hr = InvokeMethod(pWorkbooks, dispid, DISPATCH_METHOD, &vResult, 11,
&vFilename, &vUpdateLinks, &vReadOnly, &vFormat, &vPassword, &vWriteResPassword,
&vIgnoreReadOnlyRecommended, &vOrigin, &vDelimiter, &vEditable, &vNotify, &vConverter);
if (FAILED(hr))
{
printf("Could not open workbook.\n");
return FALSE;
}
pWorkbook = vResult.pdispVal;
return TRUE;
}
// 打开Excel工作表
BOOL OpenWorksheet(const char* name)
{
if (!pWorkbook)
return FALSE;
// 获取工作表集合对象
VARIANT vResult;
VariantInit(&vResult);
DISPID dispid;
HRESULT hr = GetPropertyID(pWorkbook, L"Worksheets", &dispid);
if (FAILED(hr))
{
printf("Could not get Worksheets property ID.\n");
return FALSE;
}
hr = InvokeMethod(pWorkbook, dispid, DISPATCH_PROPERTYGET, &vResult, 0);
if (FAILED(hr))
{
printf("Could not get Worksheets collection.\n");
return FALSE;
}
IDispatch* pWorksheets = vResult.pdispVal;
// 查找指定的工作表
VARIANT vName;
vName.vt = VT_BSTR;
vName.bstrVal = SysAllocStringLen(NULL, strlen(name));
MultiByteToWideChar(CP_ACP, 0, name, -1, vName.bstrVal, strlen(name));
VariantClear(&vResult);
hr = GetPropertyID(pWorksheets, L"Item", &dispid);
if (FAILED(hr))
{
printf("Could not get Item method ID.\n");
return FALSE;
}
hr = InvokeMethod(pWorksheets, dispid, DISPATCH_PROPERTYGET, &vResult, 1, &vName);
if (FAILED(hr))
{
printf("Could not get worksheet.\n");
return FALSE;
}
pWorksheet = vResult.pdispVal;
return TRUE;
}
// 读取Excel单元格数据
BOOL ReadCell(int row, int col, char* buffer, int buffer_size)
{
if (!pWorksheet)
return FALSE;
VARIANT vRow;
vRow.vt = VT_I4;
vRow.lVal = row;
VARIANT vCol;
vCol.vt = VT_I4;
vCol.lVal = col;
VARIANT vResult;
VariantInit(&vResult);
HRESULT hr = GetProperty(pWorksheet, L"Cells", &vResult, 2, &vRow, &vCol);
if (FAILED(hr))
{
printf("Could not get cell.\n");
return FALSE;
}
if (vResult.vt == VT_NULL || vResult.vt == VT_EMPTY)
{
buffer[0] = '\0';
return TRUE;
}
BSTR bstr = NULL;
hr = VariantChangeType(&vResult, &vResult, 0, VT_BSTR);
if (FAILED(hr))
{
printf("Could not convert cell data to string.\n");
return FALSE;
}
bstr = vResult.bstrVal;
WideCharToMultiByte(CP_ACP, 0, bstr, SysStringLen(bstr), buffer, buffer_size, NULL, NULL);
return TRUE;
}
// 关闭Excel应用程序
void CloseExcel()
{
if (pWorksheet)
{
pWorksheet->Release();
pWorksheet = NULL;
}
if (pWorkbook)
{
pWorkbook->Release();
pWorkbook = NULL;
}
if (pExcelApp)
{
SetProperty(pExcelApp, L"DisplayAlerts", &vtFalse);
InvokeMethod(pExcelApp, DISPID_QUIT, DISPATCH_METHOD, NULL, 0);
pExcelApp->Release();
pExcelApp = NULL;
}
// 反初始化COM库
CoUninitialize();
}
int main(int argc, char* argv[])
{
if (!OpenExcel())
{
printf("Could not open Excel application.\n");
return 1;
}
if (!OpenWorkbook("test.xlsx"))
{
printf("Could not open workbook.\n");
CloseExcel();
return 1;
}
if (!OpenWorksheet("Sheet1"))
{
printf("Could not open worksheet.\n");
CloseExcel();
return 1;
}
char buffer[256];
for (int row = 1; row <= 3; row++)
{
for (int col = 1; col <= 3; col++)
{
if (ReadCell(row, col, buffer, sizeof(buffer)))
{
printf("%s\t", buffer);
}
else
{
printf("\t");
}
}
printf("\n");
}
CloseExcel();
return 0;
}
```
在该示例中,`OpenExcel()`函数打开Excel应用程序,`OpenWorkbook()`函数打开指定的工作簿,并`OpenWorksheet()`函数打开指定的工作表。`ReadCell()`函数读取指定单元格的数据。最后,`CloseExcel()`函数关闭Excel应用程序并释放所有COM对象。
请注意,您需要包含一些帮助函数来访问COM接口,例如`SetProperty()`和`InvokeMethod()`函数:
阅读全文