yewanji 2024-01-27 15:46 采纳率: 36.3%
浏览 23
已结题

c++ 如何使用com接口调用wps实现word文档转pdf

HRESULT AutoWrap(int autoType, VARIANT* pvResult, IDispatch* pDisp, LPOLESTR ptName, int cArgs...) {
    // 变量定义
    va_list marker;
    DISPPARAMS dp = { NULL, NULL, 0, 0 };
    DISPID dispidNamed = DISPID_PROPERTYPUT;
    DISPID dispID;
    char szName[200];

    // 获取 DISPID
    pDisp->GetIDsOfNames(IID_NULL, &ptName, 1, LOCALE_USER_DEFAULT, &dispID);

    // 分配内存用于参数
    VARIANT* pArgs = new VARIANT[cArgs + 1];
    // 提取参数
    va_start(marker, cArgs);
    for (int i = 0; i < cArgs; i++) {
        pArgs[i] = va_arg(marker, VARIANT);
    }
    va_end(marker);

    // 填充 DISPPARAMS 结构
    dp.cArgs = cArgs;
    dp.rgvarg = pArgs;

    // 处理属性设置
    if (autoType & DISPATCH_PROPERTYPUT) {
        dp.cNamedArgs = 1;
        dp.rgdispidNamedArgs = &dispidNamed;
    }

    // 调用 IDispatch
    HRESULT hr = pDisp->Invoke(dispID, IID_NULL, LOCALE_SYSTEM_DEFAULT, autoType, &dp, pvResult, NULL, NULL);
    if (FAILED(hr)) {
        return hr;
    }

    // 清理
    delete[] pArgs;
    return hr;
}
int main() {
    HRESULT hr = CoInitialize(NULL); // 初始化 COM
    if (FAILED(hr)) {
        std::cout << "COM initialization failed. Error code: " << hr << std::endl;
        return 1;
    }

    // 创建 Word 应用程序实例
    CLSID clsid;
    hr = CLSIDFromProgID(L"KWPS.Application", &clsid);
    if (FAILED(hr)) {
        std::cout << "CLSIDFromProgID failed. Error code: " << hr << std::endl;
        CoUninitialize();
        return 1;
    }

    IDispatch* pWordApp;
    hr = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER, IID_IDispatch, (void**)&pWordApp);
    if (FAILED(hr)) {
        std::cout << "Word application creation failed. Error code: " << hr << std::endl;
        CoUninitialize();
        return 1;
    }

    // 设置 Word 不可见
    VARIANT x;
    x.vt = VT_I4;
    x.lVal = 0;
    hr = AutoWrap(DISPATCH_PROPERTYPUT, NULL, pWordApp, SysAllocString(L"Visible"), 1, x);
    if (FAILED(hr)) {
        std::cout << "Failed to set Word visibility. Error code: " << hr << std::endl;
        pWordApp->Release();
        CoUninitialize();
        return 1;
    }

    // 获取 Documents 集合
    VARIANT result;
    VariantInit(&result);
    hr = AutoWrap(DISPATCH_PROPERTYGET, &result, pWordApp, SysAllocString(L"Documents"), 0);
    if (FAILED(hr)) {
        std::cout << "Failed to get Documents collection. Error code: " << hr << std::endl;
        pWordApp->Release();
        CoUninitialize();
        return 1;
    }
    IDispatch* pDocuments = result.pdispVal;

    // 打开文档
    VARIANT vtFilePath;
    vtFilePath.vt = VT_BSTR;
    vtFilePath.bstrVal = ::SysAllocString(L"C:\\xxx\\wps-test\\1.docx"); // 替换为您的 Word 文档路径

    VARIANT resultDoc;
    VariantInit(&resultDoc);
    hr = AutoWrap(DISPATCH_METHOD, &resultDoc, pDocuments, SysAllocString(L"Open"), 1, vtFilePath);
    if (FAILED(hr)) {
        std::cout << "Failed to open document. Error code: " << hr << std::endl;
        pDocuments->Release();
        pWordApp->Release();
        CoUninitialize();
        return 1;
    }
    IDispatch* pDocument = resultDoc.pdispVal;
    VARIANT vtSavePath;
    vtSavePath.vt = VT_BSTR;
    vtSavePath.bstrVal = ::SysAllocString(L"C:\\xxx\\wps-test\\1.pdf"); // PDF 保存路径

    VARIANT vtFormat;
    vtFormat.vt = VT_I4;
    vtFormat.lVal = 17; // PDF 格式枚举值

    // 调用 ExportAsFixedFormat 方法
    hr = AutoWrap(DISPATCH_METHOD, NULL, pDocument, SysAllocString(L"ExportAsFixedFormat"), 2, vtSavePath, vtFormat);
    if (FAILED(hr)) {
        _com_error err(hr);
        LPCTSTR errMsg = err.ErrorMessage();
        std::wcout << L"Failed to save document as PDF. Error: " << errMsg << std::endl;
        //释放
        pDocument->Release();
        pDocuments->Release();
        pWordApp->Release();
        CoUninitialize();
        return 1;
    }

    // 关闭文档和 Word 应用程序
    hr = AutoWrap(DISPATCH_METHOD, NULL, pDocument, SysAllocString(L"Close"), 0);
    if (FAILED(hr)) {
        std::cout << "Failed to close document. Error code: " << hr << std::endl;
    }

    hr = AutoWrap(DISPATCH_METHOD, NULL, pWordApp, SysAllocString(L"Quit"), 0);
    if (FAILED(hr)) {
        std::cout << "Failed to quit Word application. Error code: " << hr << std::endl;
    }

    // 释放资源
    pDocument->Release();
    pDocuments->Release();
    pWordApp->Release();
    ::SysFreeString(vtFilePath.bstrVal);
    ::SysFreeString(vtSavePath.bstrVal);
    CoUninitialize();

    return 0;
}

以上是我写的通过c++调用com 接口的示例代码,但是发现执行到

    hr = AutoWrap(DISPATCH_METHOD, NULL, pDocument, SysAllocString(L"ExportAsFixedFormat"), 2, vtSavePath, vtFormat);

img

开始报错,说类型不匹配,我的写法是参考这个的,目前java可以实现调用wps转pdf,但是自己去封装发现有问题

   <dependency>
            <groupId>net.sf.jacob-project</groupId>
            <artifactId>jacob</artifactId>
            <version>1.14.3</version>
        </dependency>
  • 写回答

14条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-01-27 16:25
    关注

    引自免费微信小程序:皆我百晓生

    根据您提供的代码,可以尝试修改以下内容来解决类型不匹配的问题:

    1. vtFormat.lVal 的值修改为 wdExportFormatPDF,代替当前的值17。更改为vtFormat.lVal = 17,目的是将其与WPS的枚举值对应起来。

    2. 在调用 AutoWrap 函数时,在 DISPATCH_METHOD 参数之前添加一个 DISPATCH_METHOD 标志,以便指定为方法调用。

    修改后的代码如下所示:

    // 调用 ExportAsFixedFormat 方法
    hr = AutoWrap(DISPATCH_METHOD | DISPATCH_METHOD, NULL, pDocument, SysAllocString(L"ExportAsFixedFormat"), 2, vtSavePath, vtFormat);
    

    请注意,以上代码修改是基于您提供的示例代码,并根据相关文档和经验进行的推测。如果仍然出现问题,可能需要根据具体的错误信息或相关的WPS API文档进行进一步的调试和修改。

    评论 编辑记录

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 1月29日
  • 修改了问题 1月28日
  • 赞助了问题酬金15元 1月27日
  • 创建了问题 1月27日

悬赏问题

  • ¥100 科大讯飞语音唤醒词,unbuntu环境,报错
  • ¥15 可以实现这个有不同背景颜色的九九乘法表吗?
  • ¥50 python写segy数据时出错2
  • ¥20 关于R studio 做精确稳定检验的问题!(语言-r语言)
  • ¥50 用贝叶斯决策方法,设计CAD程序
  • ¥20 关于#目标检测#的问题:(qq收集表到时间才能填写,填写的份数有上限)
  • ¥50 ZYNQ7020双核FLAHS烧写的问题
  • ¥20 ue 5 中想要实现第一人称人物左右行走摆动的效果,摄像头只向右摆动一次(关键词-结点)
  • ¥15 AD9164瞬时带宽1.8G,怎么计算出来?
  • ¥15 鼠标右键,撤销删除 复制 移动,要怎样删除? HKEY_CLASSES_ROOT*\shellex\ContextMenuHandlers 没用