|
在帮林岚做一个将Excel的任意单元格的内容复制转为图片,然后将图片再另存为BMP或JPG
开始是使用excel自带的方法,先复制单元格内容,然后按住shift 点击编辑 菜单,有一个 复制为图片 的菜单项。这样图片就转到剪切板了
再对剪切板进行编程
后来发现还有有点麻烦。
就改成直接做成一个通用函数,可对任何指定的区域操作,将指定的区域内容直接转换保存为指定的文件。
一、调用方法非常的简单,方法如下: (www.Office-cn.net)
SaveRangePic Sheet1.Range("E10:F11"), "C:\tmtony.bmp"
二、值得注意的几点 1.要定义好相应的API。可放在模块或本窗体中
2.如果你的Access同时引用了word和excel,因为word 和excel都有range对象,所以要显示将函数的range改为excel.range ,否则调用将失败
或将excel的引用放在前面也可以
三、详细的API定义及通用函数的完整源码及注释- Private Declare Function OpenClipboard Lib "user32" (ByVal hwnd As Long) As Long
- Private Declare Function GetClipboardData Lib "user32" (ByVal wFormat As Integer) As Long
- Private Declare Function CloseClipboard Lib "user32" () As Long
- Private Declare Function OleCreatePictureIndirect Lib "olepro32.dll" _
- (PicDesc As uPicDesc, RefIID As GUID, ByVal fPictureOwnsHandle As Long, _
- IPic As IPicture) As Long
- '\\ 定义一个 UDT 来保存IPicture OLE接口的 GUID
- Private Type GUID
- Data1 As Long
- Data2 As Integer
- Data3 As Integer
- Data4(0 To 7) As Byte
- End Type
- '\\ 定义一个 UDT保存 bitmap信息
- Private Type uPicDesc
- Size As Long
- Type As Long
- hPic As Long
- hPal As Long
- End Type
- Private Const CF_BITMAP = 2
- Private Const PICTYPE_BITMAP = 1
- 'Office中国通用函数 可将任意Excel区域 内容复制并另存为图片
- Private Sub SaveRangePic(SourceRange As Range, FilePathName As String)
- Dim IID_IDispatch As GUID
- Dim uPicinfo As uPicDesc
- Dim IPic As IPicture
- Dim hPtr As Long
- '\\ 复制Range到剪切板 ClipBoard www.office-cn.net
- SourceRange.CopyPicture Appearance:=xlScreen, Format:=xlBitmap
- OpenClipboard 0
- hPtr = GetClipboardData(CF_BITMAP)
- CloseClipboard
- '\\ 为picture图片创建一个 GUID 接口
- With IID_IDispatch
- .Data1 = &H7BF80980
- .Data2 = &HBF32
- .Data3 = &H101A
- .Data4(0) = &H8B
- .Data4(1) = &HBB
- .Data4(2) = &H0
- .Data4(3) = &HAA
- .Data4(4) = &H0
- .Data4(5) = &H30
- .Data4(6) = &HC
- .Data4(7) = &HAB
- End With
- '\\用相关数据填充 uPicInfo
- With uPicinfo
- .Size = Len(uPicinfo) '结构体长度
- .Type = PICTYPE_BITMAP '图片类型
- .hPic = hPtr '图片句柄
- .hPal = 0 '\\ palette句柄 (如果 是 bitmap).
- End With
- '\\创建Range对应的 Picture对象
- OleCreatePictureIndirect uPicinfo, IID_IDispatch, True, IPic
- '\\另存 Picture 对象到文件
- stdole.SavePicture IPic, FilePathName
- End Sub
复制代码
四、以前网站和论坛与剪切板相关的贴子和链接(几乎涉及到剪切板的大部分操作的源码)
1.用代码插入图片到OLE对象的2种方法
http://www.access-cn.com/info/info3396.html
2.Access从剪切版里复制和粘贴数据
http://www.access-cn.com/info/info2045.html
3.最全的有关剪切板(ClipBoard)的各种操作和相关源代码集锦
http://www.office-cn.net/thread-119761-1-1.html
4.VBA保存剪贴板为Bmp(加PrtScrn截屏)
http://www.access-cn.com/info/info3461.html
5.VBA保存剪贴板为JPG(加PrtScrn截屏)
http://www.access-cn.com/info/info3460.html
五、网上搜索的相关资料(放在这里做个备忘,以免忘记),同时稍做了一下分类与整理,也给有同样问题的网友一个参考,希望对你们有用
1.将Excel整个截屏并另存为BMP文件 (测试是成功的)
- Private Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Long, ByVal dwExtraInfo As Long)
- Enum JpMode
- theScreen = 0 '全屏截图
- theForm = 1 '当前焦点窗口截图
- End Enum
- Private Declare Function GetClipboardData Lib "user32" (ByVal wFormat As Long) As Long
- Private Declare Function CloseClipboard Lib "user32" () As Long
- Private Declare Function OpenClipboard Lib "user32" (ByVal hwnd As Long) As Long
- Private Declare Function OleCreatePictureIndirect Lib "olepro32.dll" (PicDesc As PicBmp, RefIID As Guid, ByVal fPictureOwnsHandle As Long, IPic As IPicture) As Long
- Private Const CF_BITMAP = 2
- Private Type PicBmp
- Size As Long
- Type As Long
- hBmp As Long
- hPal As Long
- Reserved As Long
- End Type
- Private Type Guid
- Data1 As Long
- Data2 As Integer
- Data3 As Integer
- Data4(0 To 7) As Byte
- End Type
- Function ApiGetClipBmp() As IPicture
- On Error Resume Next
- Dim Pic As PicBmp, IID_IDispatch As Guid
- OpenClipboard 0 'OpenClipboard
- With IID_IDispatch
- .Data1 = &H20400
- .Data4(0) = &HC0
- .Data4(7) = &H46
- End With
- With Pic
- .Size = Len(Pic)
- .Type = 1
- .hBmp = GetClipboardData(CF_BITMAP)
- End With
-
- OleCreatePictureIndirect Pic, IID_IDispatch, 1, ApiGetClipBmp
- 'stdole.SavePicture ApiGetClipBmp, "c:\clipboard.bmp"
- CloseClipboard
- End Function
- Function KeyJp(Optional ByVal TheMode As JpMode = theScreen) As IPictureDisp
- '版权所有,请保留作者信息.QQ:1085992075 '如需商业用途请联系作者
- Call keybd_event(vbKeySnapshot, TheMode, 0, 0) '
- DoEvents
- 'Set KeyJp = Clipboard.GetData
- End Function
- '┗〓〓〓〓〓〓〓〓〓 KeyJp,end 〓〓〓〓〓〓〓〓〓┛
- Sub dd()
- KeyJp (theScreen)
- SavePicture ApiGetClipBmp, "c:\2.bmp"
- End Sub
复制代码
2.这个程序说起来也不复杂,涉及到两类API函数,一类是剪贴板函数,用于读取剪贴板中的位图句柄,另外一类是GDI+函数,用于位图到jpg文件的转换,具体代码如下:
- Option Explicit
- Private Declare Function OpenClipboard Lib "user32" (ByVal hwnd As Long) As Long
- Private Declare Function CloseClipboard Lib "user32" () As Long
- Private Declare Function GetClipboardData Lib "user32" (ByVal wFormat As Long) As Long
- Private Const CF_BITMAP = 2
- Private Type GUID
- Data1 As Long
- Data2 As Integer
- Data3 As Integer
- Data4(0 To 7) As Byte
- End Type
- Private Type GdiplusStartupInput
- GdiplusVersion As Long
- DebugEventCallback As Long
- SuppressBackgroundThread As Long
- SuppressExternalCodecs As Long
- End Type
- Private Type EncoderParameter
- GUID As GUID
- NumberOfValues As Long
- type As Long
- Value As Long
- End Type
- Private Type EncoderParameters
- Count As Long
- Parameter As EncoderParameter
- End Type
- Private Declare Function GdiplusStartup Lib "GDIPlus" (token As Long, inputbuf As GdiplusStartupInput, ByVal outputbuf As Long) As Long
- Private Declare Function GdiplusShutdown Lib "GDIPlus" (ByVal token As Long) As Long
- Private Declare Function GdipDisposeImage Lib "GDIPlus" (ByVal Image As Long) As Long
- Private Declare Function GdipSaveImageToFile Lib "GDIPlus" (ByVal Image As Long, ByVal filename As Long, clsidEncoder As GUID, encoderParams As Any) As Long
- Private Declare Function CLSIDFromString Lib "ole32" (ByVal str As Long, id As GUID) As Long
- Private Declare Function GdipCreateBitmapFromHBITMAP Lib "GDIPlus" (ByVal hbm As Long, ByVal hPal As Long, BITMAP As Long) As Long
- Sub test()
- Select Case CliptoJPG("c:\test.jpg")
- Case 0:
- MsgBox "剪贴板图片已保存"
- Case 1:
- MsgBox "剪贴板图片保存失败"
- Case 2:
- MsgBox "剪贴板中无图片"
- Case 3:
- MsgBox "剪贴板无法打开,可能被其他程序所占用"
- End Select
- End Sub
- Private Function CliptoJPG(ByVal destfilename As String, Optional ByVal quality As Byte = 80) As Integer
- '*****该函数用于取出剪贴板中图片转换为jpg文件另存到指定路径****
- '参数说明:
- ' destfilename:要保存的jpg文件的完整路径,必要参数;
- ' quality: jpg文件的质量,0-100之间的数值,数值越大,图片质量越高
- '返回值:
- ' 0-保存成功;1-保存失败;2-剪贴板中无位图数据;3-无法打开剪贴板
- Dim tSI As GdiplusStartupInput
- Dim lRes As Long
- Dim lGDIP As Long
- Dim lBitmap As Long
- Dim hBmp As Long
-
- '尝试打开剪贴板
- If OpenClipboard(0) Then
- '尝试取出剪贴板中位图的句柄
- hBmp = GetClipboardData(CF_BITMAP)
- '如果hBmp为0,说明剪贴板中没有存放图片
- If hBmp = 0 Then
- CliptoJPG = 2
- CloseClipboard
- Exit Function
- End If
- CloseClipboard
- Else '如果openclipboard返回0(False),说明剪贴板被其他程序所占用
- CliptoJPG = 3
- Exit Function
- End If
-
- '初始化 GDI+
- tSI.GdiplusVersion = 1
- lRes = GdiplusStartup(lGDIP, tSI, 0)
-
- If lRes = 0 Then
- '从句柄创建 GDI+ 图像
- lRes = GdipCreateBitmapFromHBITMAP(hBmp, 0, lBitmap)
-
- If lRes = 0 Then
- Dim tJpgEncoder As GUID
- Dim tParams As EncoderParameters
-
- '初始化解码器的GUID标识
- CLSIDFromString StrPtr("{557CF401-1A04-11D3-9A73-0000F81EF32E}"), tJpgEncoder
-
- '设置解码器参数
- tParams.Count = 1
- With tParams.Parameter ' Quality
- '得到Quality参数的GUID标识
- CLSIDFromString StrPtr("{1D5BE4B5-FA4A-452D-9CDD-5DB35105E7EB}"), .GUID
- .NumberOfValues = 1
- .type = 4
- .Value = VarPtr(quality)
- End With
-
- '保存图像
- lRes = GdipSaveImageToFile(lBitmap, StrPtr(destfilename), tJpgEncoder, tParams)
- If lRes = 0 Then
- CliptoJPG = 0 '转换成功
- Else
- CliptoJPG = 1 '转换失败
- End If
-
- '销毁GDI+图像
- GdipDisposeImage lBitmap
- End If
-
- '销毁 GDI+
- GdiplusShutdown lGDIP
- End If
- End Function
复制代码
|
|