Delphi Programming / Object Pascal
[掲載 2009年05月27日] [更新 2013年12月18日] エクセル操作フォームEx |
エクセル操作フォームEx 参考コード類
エクセルの画像や図形の保存 |
動作確認等 |
Windows 7 U64(SP1) + Delphi XE(UP1) Pro + Excel 2010
複数の画像を個別に保存するサンプルは Delphi XE2(UP5) |
マウスで選択中の図形類を保存 - クリップボード使用 |
クリップボードを使用した図形の保存方法です.現在選択中の図形をメタファイル,ビットマップ,JPEG画像ファイルとして保存します.画像保存ダイアログを表示するようになっています.
エクセルはワード同様,図形や画像だけを保存することはできませんが,こんな方法で保存できるというテストです. |
procedure TplExcelFormEx1.Button1Click(Sender: TObject);
var
FilePath1 : String;
FilePath2 : String;
FilePath3 : String;
AShape : Txlf2000Shape;
imgMetaFile : TMetaFile;
imgBitmap : TBitmap;
imgJpeg : TJpegImage;
strText : String;
begin
//選択したオブジェクトを取得
AShape := Txlf2000Shape(xlfExcelApp.Selection[0]);
//セル範囲などNameプロパティが取得できないもの対策
//この部分を削除すると選択しているもの全てが対象となる
try
strText := AShape.Name;
except
MessageBox(Handle, '対象外のオブジェクトです', '情報', MB_ICONINFORMATION);
exit;
end;
//クリップボードに送る
AShape.Copy;
//各画像のオブジェクトを生成
imgMetaFile := TMetaFile.Create;
imgBitmap := TBitmap.Create;
imgJpeg := TJpegImage.Create;
try
//保存先フォルダ
SavePictureDialog1.InitialDir := ExtractFilePath(Application.ExeName);
SavePictureDialog1.Filter := 'ImageFiles|*.emf;*.bmp;*.jpg';
SavePictureDialog1.FileName := StrText;
if SavePictureDialog1.Execute then begin
Update;
//各々の画像の保存名(フルパス)
FilePath1 := ChangeFileExt(SavePictureDialog1.FileName, '') + '.emf';
FilePath2 := ChangeFileExt(SavePictureDialog1.FileName, '') + '.bmp';
FilePath3 := ChangeFileExt(SavePictureDialog1.FileName, '') + '.jpg';
//メタファイルを保存
imgMetaFile.Assign(Clipboard);
imgMetaFile.SaveToFile(FilePath1);
//メタファイルをビットマップに変換して保存
imgBitmap.Width := imgMetaFile.Width;
imgBitmap.Height := imgMetaFile.Height;
imgBitmap.Canvas.Draw(0, 0, imgMetaFile);
imgBitmap.SaveToFile(FilePath2);
//ビットマップをJPEGに変換して保存
imgJpeg.Assign(imgBitmap);
imgJpeg.SaveToFile(FilePath3);
end;
finally
FreeAndNil(imgMetaFile);
FreeAndNil(imgBitmap);
FreeAndNil(imgJpeg);
end;
end;
クリップボードを使用した図形の保存方法です.指定した名前の図形をメタファイル,ビットマップ,JPEG画像ファイルとして保存します.画像保存ダイアログを表示するようになっています. |
procedure TplExcelFormEx1.Button2Click(Sender: TObject);
var
FilePath1 : String;
FilePath2 : String;
FilePath3 : String;
AShape : Txlf2000Shape;
imgMetaFile : TMetaFile;
imgBitmap : TBitmap;
imgJpeg : TJpegImage;
begin
//図形のオブジェクトを取得
AShape := xlfExcelSheet.Shapes.Item('Picture 1');
//クリップボードに送る
AShape.Copy;
//各画像のオブジェクトを生成
imgMetaFile := TMetaFile.Create;
imgBitmap := TBitmap.Create;
imgJpeg := TJpegImage.Create;
try
//保存先フォルダ
SavePictureDialog1.InitialDir := ExtractFilePath(Application.ExeName);
SavePictureDialog1.Filter := 'ImageFiles|*.emf;*.bmp;*.jpg';
SavePictureDialog1.FileName := AShape.Name;
if SavePictureDialog1.Execute then begin
Update;
//各々の画像の保存名(フルパス)
FilePath1 := ChangeFileExt(SavePictureDialog1.FileName, '') + '.emf';
FilePath2 := ChangeFileExt(SavePictureDialog1.FileName, '') + '.bmp';
FilePath3 := ChangeFileExt(SavePictureDialog1.FileName, '') + '.jpg';
//メタファイルを保存
imgMetaFile.Assign(Clipboard);
imgMetaFile.SaveToFile(FilePath1);
//メタファイルをビットマップに変換して保存
imgBitmap.Width := imgMetaFile.Width;
imgBitmap.Height := imgMetaFile.Height;
imgBitmap.Canvas.Draw(0, 0, imgMetaFile);
imgBitmap.SaveToFile(FilePath2);
//ビットマップをJPEGに変換して保存
imgJpeg.Assign(imgBitmap);
imgJpeg.SaveToFile(FilePath3);
end;
finally
FreeAndNil(imgMetaFile);
FreeAndNil(imgBitmap);
FreeAndNil(imgJpeg);
end;
end;
選択中の図形や画像の名前は,次のようなコードで確認できます. |
|
図1
図形や画像の名前 |
procedure TplExcelFormEx1.Button3Click(Sender: TObject);
var
AShape : Txlf2000Shape;
begin
xlfSetFocusExcel;
try
AShape := Txlf2000Shape(xlfExcelApp.Selection[0]);
MessageBox(Handle, PChar(AShape.Name), '情報', MB_ICONINFORMATION);
except
//何も選択されていない
end;
end;
選択した複数の画像を個別に保存 - クリップボード使用 |
エクセル操作フォームの使用例ではありませんが,エクセルでコピーした画像を,別のアプリで取得する際の参考です.クリップボードを使用すれば,選択した複数の画像を,個別に取得して保存することができます.
Excel 2007 以降では,クリップボードのデータが ZIP 形式であることを利用しています.
以下のコードは,Delphi XE2 以降専用となっていますが,ZIP 書庫の操作等の部分を書き換えれば,他のバージョンの Delphi でも利用できます.
下のコードでは「図形」は保存できません.保存可能なのは「画像」だけです.また,本サンプルは,Excel 2007 よりも前のブックの場合は機能しません. |
|
図2
複数の画像・図形を選択してコピーする |
|
図3
保存結果
|
リスト4
Delphi XE2 以降用のコード (TZipFile は Delphi XE2 以降で使用可能) |
//=============================================================================
// Art::GVML Clipformat形式のクリップボードデータの検出と保存
// docxまたはxlsx形式の文書でないと動作不可
//
// ワードの場合
// [挿入][図]はInllineでもInlineでなくとても保存可能
// [挿入][図形](オートシェイプ)はInllineでは保存不可
//
// エクセルの場合
// 画像のみ保存可能
//
// usesにClipbrd, System.Zip, StrUtilsが必要
// Delphi XE2で実装されたTZipFileを使用しているが,ZIP書庫が扱えれば何でもよい
//=============================================================================
procedure TForm1.Button1Click(Sender: TObject);
const
CustomDataStr: String = 'Art::GVML Clipformat';
var
zipStream : TMemoryStream;
hBuffer : THandle;
pBuffer : Pointer;
DataFormat : UINT;
ZipClass : TZipFile;
DestFileDir : String;
FileListArr : TArray<string>;
strText : String;
begin
//クリップボードのデータフォーマット形式の値を取得
DataFormat := RegisterClipboardFormat(PChar(CustomDataStr));
if Clipboard.HasFormat(DataFormat) then begin
//その形式だったらクリップボードからZipStreamにデータを取得
zipStream := TMemoryStream.Create;
try
ClipBoard.Open;
hBuffer := Clipboard.GetAsHandle(DataFormat);
pBuffer := GlobalLock(hBuffer);
zipStream.WriteBuffer(pBuffer^, GlobalSize(hBuffer));
zipStream.SaveToFile(ExtractFilePath(Application.ExeName) + 'Temp.zip');
GlobalUnlock(hBuffer);
Clipboard.Close;
//データ(図・画像)の保存先のフォルダを作成
DestFileDir := ExtractFilePath(Application.ExeName) + 'Temp';
ForceDirectories(DestFileDir);
//Art::GVML Clipformat形式はZip形式なのでZipからデータを取出して保存
ZipClass := TZipFile.Create;
try
zipStream.Position := 0;
ZipClass.Open(zipStream, zmRead);
FileListArr := ZipClass.FileNames;
for strText in FileListArr do begin
if ContainsText(StrText, 'clipboard/media/image') then begin
ZipClass.Extract(strText, DestFileDir, False);
end;
end;
finally
ZipClass.Close;
FreeAndNil(ZipClass);
end;
finally
FreeAndNil(zipStream);
end;
end;
end;
end.
上のコードは,ワード操作フォームEx の画像を保存するサンプルのコードで,以下の部分を削除したものとなっています. |
//選択したオブジェクトをクリップボードにコピー
wdfWordApp.Selection.Copy;
エクセル操作フォームEx で,ワード操作フォームEx のサンプルのように,選択中のオブジェクトをクリップボードにコピーするには,例えば次のコードを最初に実行します.このコードがエクセルの [コピー] ボタンクリックの代わりになります. |
//手っ取り早くOleVariant型で処理
//LSelectionはOleVariant型
LObjSelection := xlfExcelApp.Selection[0];
LObjSelection.copy;
|