我尝试将excel文件中的单元格范围保存到图片中。我使用了interop.excel api中的CopyPicture方法,因此图片应该放在剪贴板上。例如,当我在word文档上按ctrl + v时,我得到了图片,但我无法通过代码获得它。 GetImageFromClipBoard方法返回的数据为null。
public void SaveAsImage()
{
var usedRange = ws.UsedRange;
int startRow = usedRange.Row;
int endRow = startRow + usedRange.Rows.Count - 1;
int startColumn = usedRange.Column;
int endColumn = startColumn + usedRange.Columns.Count - 1;
Xl.Range rng = wb.ActiveSheet.Range[ws.Cells[1, 1],
ws.Cells[endRow, endColumn]];
rng.CopyPicture(Xl.XlPictureAppearance.xlScreen,
Xl.XlCopyPictureFormat.xlBitmap);
Image image = GetImageFromClipBoard();
image.Save("image.bmp", System.Drawing.Imaging.ImageFormat.Bmp);
}
[STAThread]
private Image GetImageFromClipBoard()
{
IDataObject clipboardData = Clipboard.GetDataObject();
Exception threadEx = null;
Thread staThread = new Thread(
delegate ()
{
try
{
clipboardData = Clipboard.GetDataObject();
}
catch (Exception ex)
{
threadEx = ex;
}
});
staThread.SetApartmentState(ApartmentState.STA);
staThread.Start();
staThread.Join();
return (Bitmap)clipboardData.GetData(DataFormats.Bitmap);
}
您要做的是从剪贴板中检索位图,类型为“位图”。不过,我不确定Office是否会使用该类型。
请注意,DataFormats
不是枚举;它们只是引用通常用于剪贴板内容的字符串ID。这立即意味着您可以添加自定义的。这些自定义的通常作为字节流放在剪贴板上。 This answer详细介绍了在剪贴板上存储和获取这些字节数组的方法。
其中一个主要使用的是DIB(基本上是没有特定文件头的BMP文件),但Office专门使用这些:
"PNG+Office Art"
"JFIF+Office Art"
"GIF+Office Art"
"PNG"
"JFIF"
"GIF"
(我听说“+ Office Art”也只是图像,但我自己没试过)
所以是的,如果你试图获取这些,用剪贴板中的字节创建一个新的MemoryStream
,并从MemoryStream中创建一个新的Bitmap
,你应该在那里。你基本上尝试它们,直到你得到一些坚持,从PNG开始。
我刚才写了一篇more detailed explanation with full code,专门用于复制和检索剪贴板上的PNG和DIB。