鱼C论坛

 找回密码
 立即注册
查看: 1799|回复: 2

C语言读取excel并存储到数组中

[复制链接]
发表于 2021-11-24 21:45:15 | 显示全部楼层 |阅读模式
30鱼币
C语言读取excel并存储到数组中

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-12-1 00:43:20 | 显示全部楼层
没人帮你写吗?那我帮你写了,就趁此机会再复习一下C语言操作 COM接口
windows 下可以用 office 提供的 COM接口来操作 office
说真的,用 C语言操作 COM接口是真的不好玩
用 VBA 多好?为什么要用不适合的工具做这件事?

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdbool.h>
  4. #include <stdarg.h>
  5. #include <windows.h>
  6. #include <combaseapi.h>

  7. VARIANT invoke(IDispatch *disp, const OLECHAR *name, WORD wFlags, size_t count, ...) {
  8.     VARIANT result = {0};
  9.     DISPID dispIdMember;
  10.     HRESULT hr = disp->lpVtbl->GetIDsOfNames(disp, &IID_NULL, (LPOLESTR *)&name, 1, LOCALE_USER_DEFAULT, &dispIdMember);
  11.     if(hr != S_OK) return result;
  12.     DISPPARAMS dp = {0};
  13.     VARIANT *rgvarg = NULL;
  14.     if(count) {
  15.         rgvarg = malloc(sizeof(VARIANT) * count);
  16.         va_list ap; va_start(ap, count);
  17.         for(size_t i = 0; i < count; ++i) {
  18.             rgvarg[i] = *va_arg(ap, VARIANT *);
  19.         }
  20.         va_end(ap);
  21.         dp.rgvarg = rgvarg;
  22.         dp.cArgs = count;
  23.     }
  24.     DISPID dispIdNamed = DISPID_PROPERTYPUT;
  25.     if(wFlags & DISPATCH_PROPERTYPUT) {
  26.         dp.rgdispidNamedArgs = &dispIdNamed;
  27.         dp.cNamedArgs = 1;
  28.     }
  29.     disp->lpVtbl->Invoke(disp, dispIdMember, &IID_NULL, LOCALE_USER_DEFAULT, wFlags, &dp, &result, NULL, NULL);
  30.     if(count) {
  31.         va_list ap; va_start(ap, count);
  32.         for(size_t i = 0; i < count; ++i) {
  33.             *va_arg(ap, VARIANT *) = rgvarg[i];
  34.         }
  35.         va_end(ap);
  36.         free(rgvarg);
  37.     }
  38.     return result;
  39. }

  40. VARIANT get_column(IDispatch *range) {
  41.     VARIANT columns = invoke(range, L"Columns", DISPATCH_PROPERTYGET, 0);
  42.     VARIANT count = invoke(columns.pdispVal, L"Count", DISPATCH_PROPERTYGET, 0);
  43.     VariantClear(&columns);
  44.     return count;
  45. }

  46. VARIANT get_row(IDispatch *range) {
  47.     VARIANT rows = invoke(range, L"Rows", DISPATCH_PROPERTYGET, 0);
  48.     VARIANT count = invoke(rows.pdispVal, L"Count", DISPATCH_PROPERTYGET, 0);
  49.     VariantClear(&rows);
  50.     return count;
  51. }

  52. int main(void) {
  53.     CoInitialize(NULL);
  54.     CLSID id;
  55.     CLSIDFromProgID(L"Excel.Application", &id);
  56.     IDispatch *Application;
  57.     CoCreateInstance(&id, NULL, CLSCTX_LOCAL_SERVER, &IID_IDispatch, (LPVOID *)&Application);
  58.     {
  59.         VARIANT boolean = {.vt = VT_BOOL, .boolVal = true};
  60.         invoke(Application, L"Visible", DISPATCH_PROPERTYPUT, 1, &boolean);
  61.         VariantClear(&boolean);
  62.     }

  63.     VARIANT wbs = invoke(Application, L"Workbooks", DISPATCH_PROPERTYGET, 0);
  64.     VARIANT filename = {.vt = VT_BSTR, .bstrVal = SysAllocString(L"C:\\cygwin64\\tmp\\test.xlsx")};
  65.     VARIANT wb = invoke(wbs.pdispVal, L"Open", DISPATCH_METHOD, 1, &filename);
  66.     VariantClear(&filename);

  67.     VARIANT wss = invoke(wb.pdispVal, L"Worksheets", DISPATCH_PROPERTYGET, 0);
  68.     VARIANT index = {.vt = VT_BSTR, .bstrVal = SysAllocString(L"Sheet1")};
  69.     VARIANT ws = invoke(wss.pdispVal, L"Item", DISPATCH_PROPERTYGET, 1, &index);
  70.     VariantClear(&index);

  71.     VARIANT range = invoke(ws.pdispVal, L"UsedRange", DISPATCH_PROPERTYGET, 0);
  72.     VARIANT column = get_column(range.pdispVal);
  73.     VARIANT row = get_row(range.pdispVal);
  74.     for(size_t y = 0; y < row.lVal; ++y) {
  75.         for(size_t x = 0; x < column.lVal; ++x) {
  76.             VARIANT vx = {.vt = VT_I4, .lVal = x + 1};
  77.             VARIANT vy = {.vt = VT_I4, .lVal = y + 1};
  78.             VARIANT cell = invoke(range.pdispVal, L"Item", DISPATCH_PROPERTYGET, 2, &vx, &vy);
  79.             VARIANT value = invoke(cell.pdispVal, L"Value", DISPATCH_PROPERTYGET, 0);
  80.             switch(value.vt) {
  81.                 case VT_BSTR:
  82.                     {
  83.                         int size = WideCharToMultiByte(CP_UTF8, 0, value.bstrVal, -1, NULL, 0, NULL, NULL);
  84.                         char *str = malloc(size);
  85.                         WideCharToMultiByte(CP_UTF8, 0, value.bstrVal, -1, str, size, NULL, NULL);
  86.                         printf("'%s' ", str);
  87.                         free(str);
  88.                     }
  89.                     break;
  90.                 case VT_R8:
  91.                     printf("'%.3lf' ", value.dblVal);
  92.                     break;
  93.                 default:
  94.                     printf("'null' ");
  95.             }
  96.             VariantClear(&value);
  97.             VariantClear(&cell);
  98.             VariantClear(&vy);
  99.             VariantClear(&vx);
  100.         }
  101.         puts("");
  102.     }
  103.     VariantClear(&row);
  104.     VariantClear(&column);
  105.     VariantClear(&range);

  106.     VariantClear(&ws);
  107.     VariantClear(&wss);

  108.     {
  109.         VARIANT boolean = {.vt = VT_BOOL, .boolVal = false};
  110.         invoke(wb.pdispVal, L"Close", DISPATCH_METHOD, 1, &boolean);
  111.         VariantClear(&boolean);
  112.     }
  113.     VariantClear(&wb);
  114.     VariantClear(&wbs);

  115.     invoke(Application, L"Quit", DISPATCH_METHOD, 0);
  116.     Application->lpVtbl->Release(Application);
  117.     CoUninitialize();
  118.     return 0;
  119. }
复制代码

  1. $ gcc -g -Wall -o main main.c -lole32 -luuid -loleaut32
  2. $ ./main
  3. 'hello world' 'main' 'printf' 'puts' 'getchar'
  4. '1234.000' '9876.000' '1024.000' '9999.000' '512.000'
  5. '文件' '开始' 'null' '数据' '视图'
  6. '帮助' 'null' '空间' 'null' 'null'
  7. 'null' 'null' 'null' 'null' 'null'
  8. '对齐方式' 'null' '检查单元格' 'null' '你好,世界'
  9. $
复制代码


1.jpg
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-12-1 14:47:20 | 显示全部楼层
来看看,答案的。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-27 09:00

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表