ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 6048|回复: 15

[分享] Word页面存为图片

[复制链接]

TA的精华主题

TA的得分主题

发表于 2017-1-27 23:38 | 显示全部楼层 |阅读模式
'Word2003的Page对象无EnhMetaFileBits方法,无法使用本方法
  1. Private Declare Function GetDC Lib "user32.dll" (ByVal hWnd As Long) As Long
  2. Private Declare Function CreateCompatibleDC Lib "gdi32.dll" (ByVal hdc As Long) As Long
  3. Private Declare Function CreateCompatibleBitmap Lib "gdi32.dll" (ByVal hdc As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long
  4. Private Declare Function SelectObject Lib "gdi32.dll" (ByVal hdc As Long, ByVal hObject As Long) As Long
  5. Private Declare Function SetEnhMetaFileBits& Lib "gdi32.dll" (ByVal DataLen&, pData As Any)
  6. Private Declare Function PlayEnhMetaFile& Lib "gdi32" (ByVal hdc&, ByVal hEMF&, pRect As Any)
  7. Private Declare Function DeleteEnhMetaFile& Lib "gdi32.dll" (ByVal hEMF As Long)
  8. Private Declare Function DeleteObject Lib "gdi32.dll" (ByVal hObject As Long) As Long
  9. Private Declare Function DeleteDC Lib "gdi32.dll" (ByVal hdc As Long) As Long
  10. Private Declare Function FillRect Lib "user32.dll" (ByVal hdc As Long, ByRef lpRect As Any, ByVal hBrush As Long) As Long
  11. Private Declare Function InvertRect Lib "user32.dll" (ByVal hdc As Long, ByRef lpRect As Any) As Long

  12. Sub MyTest()
  13. Dim aRECT(0 To 3) As Long
  14. Dim hScreenDC&
  15. Dim hMemDC&
  16. Dim hBitmap&, hBitTemp&
  17. Dim oPage As Word.Page
  18. Dim arr() As Byte, hEMF&
  19. Set oPage = ThisDocument.Windows(1).Panes(1).Pages(2)
  20. aRECT(2) = PointsToPixels(10 * oPage.Width, False) '宽度
  21. aRECT(3) = PointsToPixels(10 * oPage.Height, True)  '高度
  22. arr = oPage.EnhMetaFileBits

  23. hEMF = SetEnhMetaFileBits(UBound(arr) + 1, arr(0))

  24. hScreenDC = GetDC(0&)
  25. hMemDC = CreateCompatibleDC(hScreenDC)
  26. hBitmap = CreateCompatibleBitmap(hScreenDC, aRECT(2), aRECT(3))
  27. hBitTemp = SelectObject(hMemDC, hBitmap)

  28. InvertRect hMemDC, aRECT(0)

  29. If hEMF Then
  30.     PlayEnhMetaFile hMemDC, hEMF, aRECT(0)
  31.     DeleteEnhMetaFile hEMF  '销毁EMF
  32. End If

  33. hBitmap = SelectObject(hMemDC, hBitTemp)

  34. MsgBox SavehBitmapToFile(hBitmap, "C:\2.png", png)

  35. DeleteObject hBitmap
  36. DeleteDC hMemDC
  37. DeleteDC hScreenDC
  38. End Sub
复制代码

TA的精华主题

TA的得分主题

 楼主| 发表于 2017-1-27 23:39 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
使用了laviewpbt的代码。
  1. '**    作    者 :    laviewpbt
  2. '**    函 数 名 :    SavehBitmapToFile
  3. '**    输    入 :    Stdpic(StdPicture)        -   图象句柄
  4. '**             :    FileName(String)       -   保存路径
  5. '**             :    FileFormat(ImageFileFormat)       -   保存格式,默认jpg
  6. '**             :    JpgQuality(Long)          -   JPG图象质量
  7. '**             :    Resolution(Single)  -   设置分辨率
  8. '**    功能描述 : 把图象保存为JPG、PNG、GIF、BMP格式
  9. '**    修 改 人 :   loquat
  10. '*************************************************************************
  11. Option Explicit

  12. Private Const UnitPixel                  As Long = 2
  13. Private Const EncoderQuality             As String = "{1D5BE4B5-FA4A-452D-9CDD-5DB35105E7EB}"

  14. Private Type GdiplusStartupInput
  15.     GdiplusVersion           As Long
  16.     DebugEventCallback       As Long
  17.     SuppressBackgroundThread As Long
  18.     SuppressExternalCodecs   As Long
  19. End Type

  20. Private Enum EncoderParameterValueType
  21.     EncoderParameterValueTypeByte = 1
  22.     EncoderParameterValueTypeASCII = 2
  23.     EncoderParameterValueTypeShort = 3
  24.     EncoderParameterValueTypeLong = 4
  25.     EncoderParameterValueTypeRational = 5
  26.     EncoderParameterValueTypeLongRange = 6
  27.     EncoderParameterValueTypeUndefined = 7
  28.     EncoderParameterValueTypeRationalRange = 8
  29. End Enum

  30. Private Type EncoderParameter
  31.     GUID(0 To 3)        As Long
  32.     NumberOfValues      As Long
  33.     Type                As EncoderParameterValueType
  34.     Value               As Long
  35. End Type

  36. Private Type EncoderParameters
  37.     Count               As Long
  38.     Parameter           As EncoderParameter
  39. End Type

  40. Private Type ImageCodecInfo
  41.     ClassID(0 To 3)     As Long
  42.     FormatID(0 To 3)    As Long
  43.     CodecName           As Long
  44.     DllName             As Long
  45.     FormatDescription   As Long
  46.     FilenameExtension   As Long
  47.     MimeType            As Long
  48.     Flags               As Long
  49.     Version             As Long
  50.     SigCount            As Long
  51.     SigSize             As Long
  52.     SigPattern          As Long
  53.     SigMask             As Long
  54. End Type

  55. Private Declare Function GdiplusStartup Lib "gdiplus" (Token As Long, inputbuf As GdiplusStartupInput, Optional ByVal outputbuf As Long = 0) As Long
  56. Private Declare Sub GdiplusShutdown Lib "gdiplus" (ByVal Token As Long)
  57. Private Declare Function GdipSaveImageToFile Lib "gdiplus" (ByVal hImage As Long, ByVal sFilename As Long, clsidEncoder As Any, encoderParams As Any) As Long
  58. Private Declare Function GdipDisposeImage Lib "gdiplus" (ByVal Image As Long) As Long
  59. Private Declare Function GdipCreateBitmapFromHBITMAP Lib "gdiplus" (ByVal hbm As Long, ByVal hPal As Long, BITMAP As Long) As Long
  60. Private Declare Function GdipGetImageEncodersSize Lib "gdiplus" (numEncoders As Long, Size As Long) As Long
  61. Private Declare Function GdipGetImageEncoders Lib "gdiplus" (ByVal numEncoders As Long, ByVal Size As Long, Encoders As Any) As Long

  62. Private Declare Sub CopyMemory Lib "KERNEL32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
  63. Private Declare Function lstrlenW Lib "KERNEL32" (ByVal psString As Any) As Long
  64. Private Declare Function CLSIDFromString Lib "ole32" (ByVal lpszProgID As Long, pCLSID As Any) As Long
  65. Private Declare Function GdipBitmapSetResolution Lib "gdiplus" (ByVal BITMAP As Long, ByVal xdpi As Single, ByVal ydpi As Single) As Long


  66. Public Enum ImageFileFormat
  67.     bmp = 1
  68.     JPG = 2
  69.     png = 3
  70.     gif = 4
  71. End Enum

  72. Public Function SavehBitmapToFile(hBitmap As Long, ByVal FileName As String, _
  73.                               Optional ByVal FileFormat As ImageFileFormat = JPG, _
  74.                               Optional ByVal JpgQuality As Long = 80, _
  75.                               Optional Resolution As Single) As Boolean
  76.     Dim clsid(3)        As Long
  77.     Dim BITMAP          As Long
  78.     Dim Token           As Long
  79.     Dim Gsp             As GdiplusStartupInput

  80.     Gsp.GdiplusVersion = 1                      'GDI+ 1.0版本
  81.     GdiplusStartup Token, Gsp                   '初始化GDI+
  82.     GdipCreateBitmapFromHBITMAP hBitmap, 0, BITMAP
  83.     If BITMAP <> 0 Then                          '说明我们成功的将StdPic对象转换为GDI+的Bitmap对象了
  84.         GdipBitmapSetResolution BITMAP, Resolution, Resolution
  85.         Select Case FileFormat
  86.         Case ImageFileFormat.bmp
  87.             If Not GetEncoderClsid("Image/bmp", clsid) = -1 Then
  88.                 SavehBitmapToFile = (GdipSaveImageToFile(BITMAP, StrPtr(FileName), clsid(0), ByVal 0) = 0)
  89.             End If
  90.         Case ImageFileFormat.JPG                    'JPG格式可以设置保存的质量
  91.             Dim aEncParams()        As Byte
  92.             Dim uEncParams          As EncoderParameters
  93.             If GetEncoderClsid("Image/jpeg", clsid) <> -1 Then
  94.                 uEncParams.Count = 1                                        ' 设置自定义的编码参数,这里为1个参数
  95.                 If JpgQuality < 0 Then
  96.                     JpgQuality = 0
  97.                 ElseIf JpgQuality > 100 Then
  98.                     JpgQuality = 100
  99.                 End If
  100.                 ReDim aEncParams(1 To Len(uEncParams))
  101.                 With uEncParams.Parameter
  102.                     .NumberOfValues = 1
  103.                     .Type = EncoderParameterValueTypeLong                   ' 设置参数值的数据类型为长整型
  104.                     Call CLSIDFromString(StrPtr(EncoderQuality), .GUID(0))  ' 设置参数唯一标志的GUID,这里为编码品质
  105.                     .Value = VarPtr(JpgQuality)                                ' 设置参数的值:品质等级,最高为100,图像文件大小与品质成正比
  106.                 End With
  107.                 CopyMemory aEncParams(1), uEncParams, Len(uEncParams)
  108.                 SavehBitmapToFile = (GdipSaveImageToFile(BITMAP, StrPtr(FileName), clsid(0), aEncParams(1)) = 0)
  109.             End If
  110.         Case ImageFileFormat.png
  111.             If Not GetEncoderClsid("Image/png", clsid) = -1 Then
  112.                 SavehBitmapToFile = (GdipSaveImageToFile(BITMAP, StrPtr(FileName), clsid(0), ByVal 0) = 0)
  113.             End If
  114.         Case ImageFileFormat.gif
  115.             If Not GetEncoderClsid("Image/gif", clsid) = -1 Then                '如果原始的图像是24位,则这个函数会调用系统的调色板来将图像转换为8位,转换的效果会不尽人意,但也有可能系统不自动转换,保存失败
  116.                 SavehBitmapToFile = (GdipSaveImageToFile(BITMAP, StrPtr(FileName), clsid(0), ByVal 0) = 0)
  117.             End If
  118.         End Select
  119.     End If
  120.     GdipDisposeImage BITMAP      '注意释放资源
  121.     GdiplusShutdown Token       '关闭GDI+。
  122. End Function


  123. Private Function GetEncoderClsid(strMimeType As String, ClassID() As Long) As Long
  124.     Dim num         As Long
  125.     Dim Size        As Long
  126.     Dim i           As Long
  127.     Dim Info()      As ImageCodecInfo
  128.     Dim Buffer()    As Byte
  129.     GetEncoderClsid = -1
  130.     GdipGetImageEncodersSize num, Size               '得到解码器数组的大小
  131.     If Size <> 0 Then
  132.        ReDim Info(1 To num) As ImageCodecInfo       '给数组动态分配内存
  133.        ReDim Buffer(1 To Size) As Byte
  134.        GdipGetImageEncoders num, Size, Buffer(1)            '得到数组和字符数据
  135.        CopyMemory Info(1), Buffer(1), (Len(Info(1)) * num)     '复制类头
  136.        For i = 1 To num             '循环检测所有解码
  137.            If (StrComp(PtrToStrW(Info(i).MimeType), strMimeType, vbTextCompare) = 0) Then         '必须把指针转换成可用的字符
  138.                CopyMemory ClassID(0), Info(i).ClassID(0), 16  '保存类的ID
  139.                GetEncoderClsid = i      '返回成功的索引值
  140.                Exit For
  141.            End If
  142.        Next
  143.     End If
  144. End Function

  145. Private Function PtrToStrW(ByVal lpsz As Long) As String
  146.     Dim Out         As String
  147.     Dim Length      As Long
  148.     Length = lstrlenW(lpsz)
  149.     If Length > 0 Then
  150.         Out = VBA.StrConv(VBA.String$(Length, vbNullChar), vbUnicode)
  151.         CopyMemory ByVal Out, ByVal lpsz, Length * 2
  152.         PtrToStrW = VBA.StrConv(Out, vbFromUnicode)
  153.     End If
  154. End Function
复制代码

TA的精华主题

TA的得分主题

 楼主| 发表于 2017-1-27 23:40 | 显示全部楼层
本方法可以用于直接将Word转为图片格式的PDF等应用,不展开

TA的精华主题

TA的得分主题

发表于 2017-2-28 00:38 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
怎么使用阿,尝试了,没有成功

TA的精华主题

TA的得分主题

 楼主| 发表于 2017-2-28 12:29 | 显示全部楼层
Allen2018 发表于 2017-2-28 00:38
怎么使用阿,尝试了,没有成功

将1楼2楼的代码分别放到一个模块下,
然后运行1楼的代码,会将word文档第1页的内容存成PNG图片
aRECT(2) = PointsToPixels(10 * oPage.Width, False) '宽度
aRECT(3) = PointsToPixels(10 * oPage.Height, True)  '高度
这两行,可能不同的系统不一定能得到这么大的尺寸,遇到错误减少这个数字10即可。
调整到4以上,就算是分辨率比较高了。

TA的精华主题

TA的得分主题

发表于 2017-2-28 12:59 | 显示全部楼层
本帖最后由 Allen2018 于 2017-2-28 18:02 编辑
loquat 发表于 2017-2-28 12:29
将1楼2楼的代码分别放到一个模块下,
然后运行1楼的代码,会将word文档第1页的内容存成PNG图片
aRECT(2 ...




如截图,仍未成功!
要是能把一篇word文章导出为图片格式的pdf文件(且保持原排版),就太牛了!

文档共计一页时【添加成多页时没问题】

文档共计一页时【添加成多页时没问题】

文档共计一页时,【添加成多页时没问题】

文档共计一页时,【添加成多页时没问题】

7、4、1 * oPage.Width,时 【调小后还是不行】

7、4、1 * oPage.Width,时 【调小后还是不行】

TA的精华主题

TA的得分主题

 楼主| 发表于 2017-3-1 09:24 | 显示全部楼层
Allen2018 发表于 2017-2-28 12:59
如截图,仍未成功!
要是能把一篇word文章导出为图片格式的pdf文件(且保持原排版),就太 ...

这确实就是转图片PDF的技术,但是我就不展开了。
你应该是用的word2003吧,看1楼最前面说明

TA的精华主题

TA的得分主题

 楼主| 发表于 2017-3-1 09:25 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
Allen2018 发表于 2017-2-28 12:59
如截图,仍未成功!
要是能把一篇word文章导出为图片格式的pdf文件(且保持原排版),就太 ...

这确实就是转图片PDF的技术,但是我就不展开了。
你应该是用的word2003吧,看1楼最前面说明

TA的精华主题

TA的得分主题

发表于 2017-3-1 12:24 | 显示全部楼层
loquat 发表于 2017-3-1 09:25
这确实就是转图片PDF的技术,但是我就不展开了。
你应该是用的word2003吧,看1楼最前面说明

我用的是word2013。好的,希望能学会也可以解决我的问题

TA的精华主题

TA的得分主题

 楼主| 发表于 2017-3-1 13:14 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
pages(2)表示第2页
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-12-25 15:47 , Processed in 0.039855 second(s), 11 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表