什么是简单可靠的C库来处理Excel文件?

时间:2009-01-29 19:50:24

标签: c excel

嗯......就是这样。

我需要一些简单可靠(不必具有奇特的功能 - 我需要从Excel单元格中编写和读取文本和数字)

是的,我想要示例“Hello Cell”代码 ...

你推荐什么?

5 个答案:

答案 0 :(得分:12)

强烈气馁。我建议使用C友好格式(例如CSV)代替XLS,或使用新的XML格式(选择XML和ZIP库)。

尽管如此,要快速修复,您可以导出为引用的CSV,然后使用VBScript导入。像this这样的东西,虽然我试图让它首先在VBA中工作。

请注意,这将需要Office的副本,并且无法很好地扩展(但您可以隐藏Excel窗口)。


我刚刚找到了xlsLib,所以如果你真的需要直接用C语写,那就试一试吧!但要小心,因为很难做到正确,特别是如果你要写现有的文件。

还存在LibExcel,但那是C ++,所以你需要编译一个包装器,或者为C重写。


最后一个警告:我一开始没有搜索这些内容的原因是它很难做到正确。我没有使用上面的库,但我怀疑他们会以奇怪和不寻常的方式打破。我相信您已阅读Joel's处理Office格式。

答案 1 :(得分:12)

Excel与其他Office产品一样,通过COM导出其内容。这可用于C ++,VB,C#以及其他任何具有COM互操作的语言 - 前提是您在Windows中运行并安装了Excel。 (你不能从普通的C到达COM。这是幸运的还是不幸的取决于你。)

然而,对于非托管语言来说,COM是一种血腥的混乱痛苦。以下VB:

Set objExcel = CreateObject("Excel.Application")  ' start or use existing Excel
objExcel.Visible = True                           ' show the window
objExcel.Workbooks.Add                            ' create an empty workbook

大致翻译成以下C ++:

#include <assert.h>
#include <ole2.h>
#include <tchar.h>

int main() {
    HRESULT hr;
    IDispatch *objExcel, *objWorkbooks;
    CLSID clsid;
    DISPID id, id2;
    DISPPARAMS p;
    VARIANT v;
    TCHAR *name;

    CoInitialize(NULL);

    hr = CLSIDFromProgID(_T("Excel.Application"), &clsid);
    assert(SUCCEEDED(hr));
    hr = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER,
            IID_IDispatch, (LPVOID *)&objExcel);
    assert(SUCCEEDED(hr));

    id2 = DISPID_PROPERTYPUT;
    name = _T("Visible");
    hr = objExcel->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &id);
    assert(SUCCEEDED(hr));
    VariantInit(&v);
    v.vt = VT_I4;
    v.lVal = 1;
    p.cArgs = 1;
    p.rgvarg = &v;
    p.cNamedArgs = 1;
    p.rgdispidNamedArgs = &id2;
    hr = objExcel->Invoke(id, IID_NULL, LOCALE_SYSTEM_DEFAULT,
            DISPATCH_PROPERTYPUT, &p, NULL, NULL, NULL);
    assert(SUCCEEDED(hr));

    name = _T("Workbooks");
    hr = objExcel->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &id);
    assert(SUCCEEDED(hr));
    p.cArgs = 0;
    p.rgvarg = NULL;
    p.cNamedArgs = 0;
    p.rgdispidNamedArgs = NULL;
    hr = objExcel->Invoke(id, IID_NULL, LOCALE_SYSTEM_DEFAULT,
            DISPATCH_PROPERTYGET, &p, &v, NULL, NULL);
    assert(SUCCEEDED(hr));
    objWorkbooks = v.pdispVal;

    name = _T("Add");
    hr = objWorkbooks->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &id);
    assert(SUCCEEDED(hr));
    p.cArgs = 0;
    p.rgvarg = NULL;
    p.cNamedArgs = 0;
    p.rgdispidNamedArgs = NULL;
    hr = objWorkbooks->Invoke(id, IID_NULL, LOCALE_SYSTEM_DEFAULT,
            DISPATCH_PROPERTYGET, &p, NULL, NULL, NULL);
    assert(SUCCEEDED(hr));

    return 0;
}

答案 2 :(得分:3)

一个免费的库,但这又是C ++,而不是C: ExcelFormat

答案 3 :(得分:2)

我对ephemient发布的内容进行了一次小扩展。有一个非常方便的库可以轻松使用IDispatch界面。 http://disphelper.sourceforge.net/

这只是你添加到项目中的一个文件,但它使用C语言进行IDispatch编程几乎是有趣的; - )

答案 4 :(得分:1)

另一种选择是使用libxlsxwriter,一个用于编写 Excel XLSX文件的C库。但是,它无法读取 Excel文件,并且它不支持XLS文件。