C++ 调用 WPS 接口实现文字高效写入全解析

#include <windows.h>
#include <ole2.h>
#include <iostream>
#include <string>

// 转换宽字符字符串到多字节字符串
std::string WideToMultiByte(const std::wstring& wstr) {
    int len = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, NULL, 0, NULL, NULL);
    if (len == 0) {
        return "";
    }
    char* buffer = new char[len];
    WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, buffer, len, NULL, NULL);
    std::string result(buffer);
    delete[] buffer;
    return result;
}

// 转换多字节字符串到宽字符字符串
std::wstring MultiByteToWide(const std::string& str) {
    int len = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, NULL, 0);
    if (len == 0) {
        return L"";
    }
    wchar_t* buffer = new wchar_t[len];
    MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, buffer, len);
    std::wstring result(buffer);
    delete[] buffer;
    return result;
}

int main() {
    // 初始化COM库
    HRESULT hr = CoInitialize(NULL);
    if (FAILED(hr)) {
        std::cerr << "无法初始化COM库,错误码: " << hr << std::endl;
        return 1;
    }

    // 创建WPS应用程序对象
    CLSID clsid;
    hr = CLSIDFromProgID(L"wps.Application", &clsid);
    if (FAILED(hr)) {
        std::cerr << "无法获取WPS应用程序的CLSID,错误码: " << hr << std::endl;
        CoUninitialize();
        return 1;
    }

    IDispatch* pWpsApp = NULL;
    hr = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER, IID_IDispatch, (void**)&pWpsApp);
    if (FAILED(hr) || pWpsApp == NULL) {
        std::cerr << "无法创建WPS应用程序实例,错误码: " << hr << std::endl;
        CoUninitialize();
        return 1;
    }

    // 设置WPS应用程序可见(可选)
    DISPID dispid;
    OLECHAR* methodName = L"Visible";
    hr = pWpsApp->GetIDsOfNames(IID_NULL, &methodName, 1, LOCALE_SYSTEM_DEFAULT, &dispid);
    if (SUCCEEDED(hr)) {
        VARIANT var;
        var.vt = VT_BOOL;
        var.boolVal = VARIANT_TRUE;
        DISPPARAMS params = { NULL, NULL, 0, 0 };
        params.cArgs = 1;
        params.rgvarg = &var;
        params.cNamedArgs = 0;
        pWpsApp->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYPUT, &params, NULL, NULL, NULL);
    }

    // 获取Documents集合
    IDispatch* pDocuments = NULL;
    methodName = L"Documents";
    hr = pWpsApp->GetIDsOfNames(IID_NULL, &methodName, 1, LOCALE_SYSTEM_DEFAULT, &dispid);
    if (SUCCEEDED(hr)) {
        DISPPARAMS params = { NULL, NULL, 0, 0 };
        VARIANT result;
        VariantInit(&result);
        hr = pWpsApp->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, &params, &result, NULL, NULL);
        if (SUCCEEDED(hr) && result.vt == VT_DISPATCH) {
            pDocuments = result.pdispVal;
        }
    }

    if (pDocuments == NULL) {
        std::cerr << "无法获取Documents集合" << std::endl;
        pWpsApp->Release();
        CoUninitialize();
        return 1;
    }

    // 创建新文档
    IDispatch* pDocument = NULL;
    methodName = L"Add";
    hr = pDocuments->GetIDsOfNames(IID_NULL, &methodName, 1, LOCALE_SYSTEM_DEFAULT, &dispid);
    if (SUCCEEDED(hr)) {
        DISPPARAMS params = { NULL, NULL, 0, 0 };
        VARIANT result;
        VariantInit(&result);
        hr = pDocuments->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &params, &result, NULL, NULL);
        if (SUCCEEDED(hr) && result.vt == VT_DISPATCH) {
            pDocument = result.pdispVal;
        }
    }

    pDocuments->Release();

    if (pDocument == NULL) {
        std::cerr << "无法创建新文档" << std::endl;
        pWpsApp->Release();
        CoUninitialize();
        return 1;
    }

    // 获取Selection对象
    IDispatch* pSelection = NULL;
    methodName = L"Selection";
    hr = pWpsApp->GetIDsOfNames(IID_NULL, &methodName, 1, LOCALE_SYSTEM_DEFAULT, &dispid);
    if (SUCCEEDED(hr)) {
        DISPPARAMS params = { NULL, NULL, 0, 0 };
        VARIANT result;
        VariantInit(&result);
        hr = pWpsApp->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, &params, &result, NULL, NULL);
        if (SUCCEEDED(hr) && result.vt == VT_DISPATCH) {
            pSelection = result.pdispVal;
        }
    }

    if (pSelection == NULL) {
        std::cerr << "无法获取Selection对象" << std::endl;
        pDocument->Release();
        pWpsApp->Release();
        CoUninitialize();
        return 1;
    }

    // 在文档中写入文字
    methodName = L"TypeText";
    hr = pSelection->GetIDsOfNames(IID_NULL, &methodName, 1, LOCALE_SYSTEM_DEFAULT, &dispid);
    if (SUCCEEDED(hr)) {
        VARIANT var;
        var.vt = VT_BSTR;
        var.bstrVal = SysAllocString(L"这是由C++程序写入WPS文档的示例文本。\n");
        
        DISPPARAMS params = { NULL, NULL, 0, 0 };
        params.cArgs = 1;
        params.rgvarg = &var;
        params.cNamedArgs = 0;
        
        pSelection->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &params, NULL, NULL, NULL);
        SysFreeString(var.bstrVal);
    }

    // 保存文档
    methodName = L"SaveAs";
    hr = pDocument->GetIDsOfNames(IID_NULL, &methodName, 1, LOCALE_SYSTEM_DEFAULT, &dispid);
    if (SUCCEEDED(hr)) {
        VARIANT varFileName;
        varFileName.vt = VT_BSTR;
        varFileName.bstrVal = SysAllocString(L"D:\\WPSCSharpTest.docx"); // 请确保路径存在
        
        DISPPARAMS params = { NULL, NULL, 0, 0 };
        params.cArgs = 1;
        params.rgvarg = &varFileName;
        params.cNamedArgs = 0;
        
        pDocument->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &params, NULL, NULL, NULL);
        SysFreeString(varFileName.bstrVal);
    }

    // 关闭文档
    methodName = L"Close";
    hr = pDocument->GetIDsOfNames(IID_NULL, &methodName, 1, LOCALE_SYSTEM_DEFAULT, &dispid);
    if (SUCCEEDED(hr)) {
        DISPPARAMS params = { NULL, NULL, 0, 0 };
        pDocument->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &params, NULL, NULL, NULL);
    }

    // 退出WPS应用程序
    methodName = L"Quit";
    hr = pWpsApp->GetIDsOfNames(IID_NULL, &methodName, 1, LOCALE_SYSTEM_DEFAULT, &dispid);
    if (SUCCEEDED(hr)) {
        DISPPARAMS params = { NULL, NULL, 0, 0 };
        pWpsApp->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &params, NULL, NULL, NULL);
    }

    // 释放COM对象
    if (pSelection) pSelection->Release();
    if (pDocument) pDocument->Release();
    if (pWpsApp) pWpsApp->Release();

    // 释放COM库
    CoUninitialize();

    std::cout << "文字已成功写入WPS文档!" << std::endl;
    return 0;
}    

上述代码实现了 C++ 通过 COM 接口调用 WPS 并写入文字的功能。代码主要完成以下工作:

  1. 初始化 COM 库,这是使用 COM 接口的基础
  2. 创建 WPS 应用程序实例并设置为可见
  3. 创建新的文档
  4. 获取文档的 Selection 对象,用于操作文本插入位置
  5. 调用 TypeText 方法向文档中写入文字
  6. 将文档保存到指定路径
  7. 关闭文档并退出 WPS 应用程序
  8. 释放所有 COM 对象并清理 COM 库资源

使用这段代码前需要注意:

  1. 系统中需要安装 WPS Office
  2. 确保有写入指定路径文件的权限
  3. 代码中使用的是 WPS 的 COM 接口,可能需要根据实际 WPS 版本做适当调整
  4. 如需操作已存在的文档,需要使用 Open 方法而非 Add 方法
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

三希

如果这篇文章帮您解决了技术难题

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值