0

我有一个 Excel 电子表格,它是一张带有表格和图表的表格。我需要做的是将此添加到 PDF 中。我使用的 PDF API 不支持导入 Excel 文档,所以我想知道 C++ 是否有任何方法可以将 Excel 文档保存/转换为 Jpeg(或 BMP)?

补充一点,显然这必须在 C++ 中作为现有应用程序的一部分来完成,该应用程序每次运行时都会创建 PDF。我不会问这个问题是否可以手动完成。

4

2 回答 2

2

好吧,经过大量的努力和拉扯,我设法回答了我自己的问题。与其他答案中所说的相反,可以将 Excel 电子表格保存为 Jpeg(尽管我坚持使用位图格式,因为这对我来说已经足够了。转换为 jpeg 很容易)。我通过 Excel API 所做的是选择使用的范围。从那里,我将它作为图片复制到剪贴板,然后获取剪贴板数据并将其转换为具有 IPicture 接口的图片对象。从那里,创建一个流并将其复制到流中,然后再将此流保存到文件中。结果是一个 bmp 文件,其中包含我所追求的图像。下面的代码示例。

    CRange range = sheet.get_UsedRange();

    range.CopyPicture(Excel::xlScreen, Excel::xlBitmap);

    if (IsClipboardFormatAvailable(CF_BITMAP)) // just to be sure it copied
    {
        if (OpenClipboard(NULL) > 0)
        {
            // save clipboard as bmp
            HBITMAP hBitmap = (HBITMAP)GetClipboardData(CF_BITMAP);

            SaveBitmap(ps_filename, hBitmap, NULL);

            CloseClipboard();
        }
    }
}

bool CExcelDocument::SaveBitmap(LPCSTR filename, HBITMAP bmp, HPALETTE pal)
{
    bool bReturn = false;
    PICTDESC pictdesc;
    LPPICTURE pPicture;

    ::ZeroMemory( &pictdesc, sizeof(pictdesc) );
    pictdesc.picType        = PICTYPE_BITMAP;
    pictdesc.bmp.hbitmap    = bmp;
    pictdesc.bmp.hpal       = pal;
    pictdesc.cbSizeofstruct = sizeof(PICTDESC);

    HRESULT hr = OleCreatePictureIndirect(&pictdesc, IID_IPicture, false, reinterpret_cast<void**>(&pPicture));

    if (!SUCCEEDED(hr))
        return false;

    LPSTREAM pStream;
    hr = CreateStreamOnHGlobal(0, true, &pStream);

    if (!SUCCEEDED(hr))
    {
        pPicture->Release();
        return false;
    }

    LONG lBytesRead = 0;
    DWORD lBytesWritten = 0;
    hr = pPicture->SaveAsFile(pStream, true, &lBytesRead);

    if (!SUCCEEDED(hr))
    {
        pStream->Release();
        pPicture->Release();
        return false;
    }

    HANDLE hFile = CreateFile(filename, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);

    if (!hFile)
    {
        return false;
    }

    HGLOBAL hMemory = 0;
    GetHGlobalFromStream(pStream, &hMemory);
    LPVOID pData = GlobalLock(hMemory);

    bReturn = !!WriteFile(hFile, pData, lBytesRead, &lBytesWritten, 0);
    bReturn &= (lBytesWritten == static_cast<DWORD>(lBytesRead));

    GlobalUnlock(hMemory);
    CloseHandle(hFile);

    pStream->Release();
    pPicture->Release();

    return bReturn;
}
于 2012-04-18T10:11:32.210 回答
-1

您可以做的是,使用 Execl API ( Office Interop ) 将电子表格加载到 C++ 中。现在您可以访问行和列中的值。您还应该能够提取它们的大小(宽度和高度)。这是你的起点。

现在最简单的方法是使用 GDI(或其他)创建一张新图片并遍历 Excel 工作表中的每个单元格并将其内容绘制到图片中。在此之后,您可以绘制类似于单元格本身的线条。

无论如何,这会导致大量工作并且并不容易,特别是如果您必须考虑单元格内的文本对齐和边框大小等问题。

于 2012-04-16T09:21:23.760 回答