2012-04-16 77 views
0

我有一張Excel電子表格,裏面有一張表格和一張圖表。我需要做的是將其添加到PDF中。我正在使用的PDF API不支持導入Excel文檔,所以我想知道是否有任何方式從C++將Excel文檔保存/轉換爲Jpeg(或BMP)?將Excel電子表格保存爲C++中的Jpeg?

只需添加,顯然這必須在C++中完成,作爲現有應用程序的一部分,該應用程序每次運行時都會創建PDF。我不會問這是否可以手動完成的一個問題。

+1

這只是一次性的事情嗎?似乎你可以打開電子表格並按下打印屏幕並將其粘貼到mspaint中。 – Tim 2012-04-16 08:24:34

+0

當然不是。這必須在C++中完成,作爲現有流程的一部分。 – Jonnster 2012-04-16 08:35:28

+0

@Jonnster:你想要導出**完整的** excel表還是可以,如果你只是看到它的可見部分? – 2012-04-16 08:47:49

回答

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; 
} 
-1

您可以做的是使用Execl API(Office Interop)將電子表格加載到C++中。現在您可以訪問行和列中的值。你也應該能夠提取它們的大小(寬度和高度)。這是你的出發點。

現在最簡單的方法是使用GDI(或其他)來創建一張新圖片,並瀏覽Excel表格中的每個單元格,並將其內容繪製到您的圖片中。在此之後,您可以繪製類似細胞本身的線條。

無論如何,這會導致很多工作,並且不會很容易,尤其是如果您必須考慮單元格內的文本對齊和邊框尺寸等。