2012-04-16 9 views
0

私はテーブルとチャートが1枚あるExcelスプレッドシートを持っています。私がする必要があるのは、これをPDFに追加することです。私が使用しているPDF APIはExcelドキュメントのインポートをサポートしていないので、ExcelドキュメントをJpeg(またはBMP)に保存/変換する方法があるかどうかは疑問でしたか?ExcelスプレッドシートをJpegとしてC++で保存しますか?

これを追加するだけで、実行するたびにPDFを作成する既存のアプリケーションの一部として、これをC++で行う必要があります。私はそれが単なる手作業で行えるものなのかどうかという質問をしていないだろう。

+1

これは単なる1回限りですか?スプレッドシートを開き、印刷画面を押してmspaintに貼り付けることができるようです。 – Tim

+0

もちろんです。これは、既存のプロセスの一部としてC++で行われなければなりません。 – Jonnster

+0

@Jonnster:** complete ** Excelシートをエクスポートしたいのですか、それとも目に見える部分があればOKですか? –

答えて

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++に読み込むことです。これで、行と列内の値にアクセスできるようになりました。また、それらの大きさ(幅と高さ)を抽出することもできます。これがあなたの出発点です。

最も簡単な方法は、新しい画像を作成し、Excelシート内のすべてのセルを歩き回り、その内容を画像に描画するためにGDI(または何でも)を使用することです。この後、セルそのものに似た線を描くことができます。

とにかくこれは多くの仕事をもたらし、特にセル内のテキストの整列や境界線のサイズなどを考慮する必要がある場合は、簡単ではありません。