0

表とグラフが入った1枚のExcelスプレッドシートがあります。私がする必要があるのは、これをPDFに追加することです。私が使用しているPDFAPIはExcelドキュメントのインポートをサポートしていないので、C ++からExcelドキュメントをJpeg(またはBMP)に保存/変換する方法があるかどうか疑問に思いました。

追加するだけで、明らかにこれは、実行されるたびにPDFを作成する既存のアプリケーションの一部としてC++で実行する必要があります。手動で実行できる1回限りの場合は、質問しません。

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 に答える