【问题标题】:Converting xls file into PDF in via cpp通过cpp将xls文件转换为PDF
【发布时间】:2021-08-25 05:19:54
【问题描述】:

我在 Visual Studio 2019 社区工作,我正在 cpp 中编写 MFC 应用程序。我想在对话框中添加一个功能 - 当按下按钮时,它将现有的 xls 文件转换为 pdf 文件。我已经尝试将扩展名Aspose.Cells.CppAspose.PDF.Cppthis 代码一起使用,但是我在DLL 本身的代码中遇到了很多错误。我也尝试从here 安装libHARU,但我没能成功。

我尝试在 cpp 中的 MFC 应用程序中寻找另一种将 xls 转换为 pdf 的方法,或者寻找另一种用于创建桌面应用程序的环境(它具有一些基本功能,例如在 MFC 中添加按下按钮,所以我不必使用 Win32 API 从头开始​​编写所有内容),但我什么也没找到。也许有人可以向我解释如何在 cpp 中执行这种转换,以便我可以在编写 MFC 应用程序时使用它,或者可以向我推荐一些有关创建支持这种类型转换的应用程序的另一种方法的有用信息?

【问题讨论】:

  • 任何用任何能够读写文件的编程语言编写的程序都可以从一种文档编码转换为另一种文档编码。更改应用程序模型不会让您更接近解决方案。您似乎严重低估了从 x 转换为 y 所需的努力(xMS-XLS,在文档中描述超过 1000 页)。 PDF 文档的页数略低于 1000 页。这就是您要解决的问题。
  • 在我的 MFC 应用程序中,我只是让用户使用 PDF 打印机 ...
  • 它只是用户自己使用应用程序的打印机。
  • 这不是免费的,所以可能是另一种解决方案:bullzip.com/developer.php
  • 我不知道。对不起。我想这就是api的用途。看起来价格合理。

标签: c++ visual-studio mfc xls


【解决方案1】:

您在 cmets 中对我说,您可以假设用户在他的机器上安装了 Excel。如果是这样,那么您可以使用 Excel 的自动化对象模型来操作 Excel。你可以做类似#import 类型库之类的东西......也许这会使 C++ 更漂亮。然而,我在驱动 Office 应用程序方面的经验是更多地坚持使用原始调度指针。这样我就少出错了。这可能需要更多的错误检查和其他东西,但这取决于你。

...还有一个很大的警告。这是一个交互式应用程序......我假设你使用的是 MFC 主题。对于一项服务,Microsoft 不建议您以这种方式驱动他们的 Office 应用程序。我在一个 .xlsx 文件上对此进行了测试,它确实有效。假设它也适用于 .xls。对于其他格式,您可能需要使用不同的导入函数。

void ConvertFile(LPCWSTR lpszFileIn, LPCWSTR lpszFileOut)
{
    CComDispatchDriver excel;
    if (SUCCEEDED(excel.CoCreateInstance(_T("Excel.Application"), NULL, CLSCTX_LOCAL_SERVER)))
    {
        _variant_t vWorkbooks;
        if (SUCCEEDED(excel.GetPropertyByName(L"Workbooks", &vWorkbooks)))
        {
            CComDispatchDriver workbooks(vWorkbooks.pdispVal);

            _variant_t vWorksheet;
            if (SUCCEEDED(workbooks.Invoke1(L"Open", &_variant_t(lpszFileIn), &vWorksheet)))
            {
                CComDispatchDriver worksheet(vWorksheet.pdispVal);

                UINT xlTypePdf = 0;
                HRESULT hr = worksheet.Invoke2(L"ExportAsFixedFOrmat", &_variant_t(xlTypePdf), &_variant_t(lpszFileOut), NULL);
                if (FAILED(hr))
                {
                    _com_error err(hr);
                    AfxMessageBox(err.ErrorMessage());
                }

            }

        }
        excel.Invoke0(L"Quit", NULL);
    }
}

【讨论】:

    【解决方案2】:

    我会给出一个解决方案,但是这个不使用c++,只是命令行和LibreOffice app:

    使用命令行 Libre Office 工具:--convert-to

    --convert-to output_file_extension[:output_filter_name] [--outdir output_dir] files
    
    Batch convert files. If --outdir is not specified, then current working directory is used as output_dir.
    Eg. --convert-to pdf *.doc
    --convert-to pdf:writer_pdf_Export --outdir /home/user *.doc
    

    有关如何使用此命令的更多详细信息,您可以在此处找到:https://help.libreoffice.org/Common/Starting_the_Software_With_Parameters

    稍后编辑:下面是如何在 C++/MFC 代码中实现上述解决方案的示例:

    STARTUPINFO si = { 0 };
    si.cb = sizeof(si);
    PROCESS_INFORMATION pi = { 0 };
    sCommand.Format(_T("C:\\WINDOWS\\System32\\cmd.exe /c
    C:\\LibreOffice\\program\\swriter.exe --convert-to pdf -outdir
    c:\\temp\\  c:\\temp\\MyFile.doc"));
    ::CreateProcess(0, sCommand, 0, 0, TRUE, CREATE_NO_WINDOW, 0, 0, &si, &pi);
    

    【讨论】:

    • 非常感谢您的评论。我正在寻找可以集成到我正在编写的 MFC 应用程序中的东西。我不确定,也许您知道是否可以从我的应用程序中使用命令行和 LibreOffice 应用程序?
    • 我认为如果不使用 PDF 库,无论是否免费,您都无法解决您的任务。
    • 如果在您的客户机器上安装 LibreOffice 的要求以及此应用程序生成的结果对您来说是可以接受的,那么从您的应用程序中使用命令行应用程序是没有问题的。您可以只调用CreateProcess() 函数(通过命令行),等待它的句柄(WaitForSingleObject())直到它完成,最后调用GetExitCodeProcess() 来检查它的返回码(看看它是否成功或什么出错)。上面的过程是阻塞的(实际上WaitForSingleObject() 调用是阻塞的)。
    • @E. Ginzburg 你可以做任何你想做的事情,但你需要知道你可以通过编程方式执行命令行命令来进行转换,但是,我想使用CreateProcess 更可靠地完成你的任务,我只想知道有这个替代品。
    • 正如我上面提到的,如果 LibreOffice 解决方案及其结果对您来说没问题(首先在 CMD 窗口中手动测试它们,并弄清楚它将如何部署到用户的机器上),所有你需要的是从你的应用程序调用命令行。如果您在使用我上面列出的功能时遇到问题,最好启动一个新线程,因为它是一个不同的主题(如何运行一般的命令行应用程序,而不是特定于 xls 到 pdf 的转换)。不过,您可能会得到负面评价,因为已经发布了很多问题和示例。
    猜你喜欢
    • 1970-01-01
    • 2012-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-10
    • 2014-11-20
    • 1970-01-01
    相关资源
    最近更新 更多