C语言读取excel并存储到数组中
C语言读取excel并存储到数组中 没人帮你写吗?那我帮你写了,就趁此机会再复习一下C语言操作 COM接口windows 下可以用 office 提供的 COM接口来操作 office
说真的,用 C语言操作 COM接口是真的不好玩
用 VBA 多好?为什么要用不适合的工具做这件事?
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdarg.h>
#include <windows.h>
#include <combaseapi.h>
VARIANT invoke(IDispatch *disp, const OLECHAR *name, WORD wFlags, size_t count, ...) {
VARIANT result = {0};
DISPID dispIdMember;
HRESULT hr = disp->lpVtbl->GetIDsOfNames(disp, &IID_NULL, (LPOLESTR *)&name, 1, LOCALE_USER_DEFAULT, &dispIdMember);
if(hr != S_OK) return result;
DISPPARAMS dp = {0};
VARIANT *rgvarg = NULL;
if(count) {
rgvarg = malloc(sizeof(VARIANT) * count);
va_list ap; va_start(ap, count);
for(size_t i = 0; i < count; ++i) {
rgvarg = *va_arg(ap, VARIANT *);
}
va_end(ap);
dp.rgvarg = rgvarg;
dp.cArgs = count;
}
DISPID dispIdNamed = DISPID_PROPERTYPUT;
if(wFlags & DISPATCH_PROPERTYPUT) {
dp.rgdispidNamedArgs = &dispIdNamed;
dp.cNamedArgs = 1;
}
disp->lpVtbl->Invoke(disp, dispIdMember, &IID_NULL, LOCALE_USER_DEFAULT, wFlags, &dp, &result, NULL, NULL);
if(count) {
va_list ap; va_start(ap, count);
for(size_t i = 0; i < count; ++i) {
*va_arg(ap, VARIANT *) = rgvarg;
}
va_end(ap);
free(rgvarg);
}
return result;
}
VARIANT get_column(IDispatch *range) {
VARIANT columns = invoke(range, L"Columns", DISPATCH_PROPERTYGET, 0);
VARIANT count = invoke(columns.pdispVal, L"Count", DISPATCH_PROPERTYGET, 0);
VariantClear(&columns);
return count;
}
VARIANT get_row(IDispatch *range) {
VARIANT rows = invoke(range, L"Rows", DISPATCH_PROPERTYGET, 0);
VARIANT count = invoke(rows.pdispVal, L"Count", DISPATCH_PROPERTYGET, 0);
VariantClear(&rows);
return count;
}
int main(void) {
CoInitialize(NULL);
CLSID id;
CLSIDFromProgID(L"Excel.Application", &id);
IDispatch *Application;
CoCreateInstance(&id, NULL, CLSCTX_LOCAL_SERVER, &IID_IDispatch, (LPVOID *)&Application);
{
VARIANT boolean = {.vt = VT_BOOL, .boolVal = true};
invoke(Application, L"Visible", DISPATCH_PROPERTYPUT, 1, &boolean);
VariantClear(&boolean);
}
VARIANT wbs = invoke(Application, L"Workbooks", DISPATCH_PROPERTYGET, 0);
VARIANT filename = {.vt = VT_BSTR, .bstrVal = SysAllocString(L"C:\\cygwin64\\tmp\\test.xlsx")};
VARIANT wb = invoke(wbs.pdispVal, L"Open", DISPATCH_METHOD, 1, &filename);
VariantClear(&filename);
VARIANT wss = invoke(wb.pdispVal, L"Worksheets", DISPATCH_PROPERTYGET, 0);
VARIANT index = {.vt = VT_BSTR, .bstrVal = SysAllocString(L"Sheet1")};
VARIANT ws = invoke(wss.pdispVal, L"Item", DISPATCH_PROPERTYGET, 1, &index);
VariantClear(&index);
VARIANT range = invoke(ws.pdispVal, L"UsedRange", DISPATCH_PROPERTYGET, 0);
VARIANT column = get_column(range.pdispVal);
VARIANT row = get_row(range.pdispVal);
for(size_t y = 0; y < row.lVal; ++y) {
for(size_t x = 0; x < column.lVal; ++x) {
VARIANT vx = {.vt = VT_I4, .lVal = x + 1};
VARIANT vy = {.vt = VT_I4, .lVal = y + 1};
VARIANT cell = invoke(range.pdispVal, L"Item", DISPATCH_PROPERTYGET, 2, &vx, &vy);
VARIANT value = invoke(cell.pdispVal, L"Value", DISPATCH_PROPERTYGET, 0);
switch(value.vt) {
case VT_BSTR:
{
int size = WideCharToMultiByte(CP_UTF8, 0, value.bstrVal, -1, NULL, 0, NULL, NULL);
char *str = malloc(size);
WideCharToMultiByte(CP_UTF8, 0, value.bstrVal, -1, str, size, NULL, NULL);
printf("'%s' ", str);
free(str);
}
break;
case VT_R8:
printf("'%.3lf' ", value.dblVal);
break;
default:
printf("'null' ");
}
VariantClear(&value);
VariantClear(&cell);
VariantClear(&vy);
VariantClear(&vx);
}
puts("");
}
VariantClear(&row);
VariantClear(&column);
VariantClear(&range);
VariantClear(&ws);
VariantClear(&wss);
{
VARIANT boolean = {.vt = VT_BOOL, .boolVal = false};
invoke(wb.pdispVal, L"Close", DISPATCH_METHOD, 1, &boolean);
VariantClear(&boolean);
}
VariantClear(&wb);
VariantClear(&wbs);
invoke(Application, L"Quit", DISPATCH_METHOD, 0);
Application->lpVtbl->Release(Application);
CoUninitialize();
return 0;
}
$ gcc -g -Wall -o main main.c -lole32 -luuid -loleaut32
$ ./main
'hello world' 'main' 'printf' 'puts' 'getchar'
'1234.000' '9876.000' '1024.000' '9999.000' '512.000'
'文件' '开始' 'null' '数据' '视图'
'帮助' 'null' '空间' 'null' 'null'
'null' 'null' 'null' 'null' 'null'
'对齐方式' 'null' '检查单元格' 'null' '你好,世界'
$
来看看,答案的。
页:
[1]