2016-08-23 70 views
0

以下是用于将doc文件转换为image.this的代码,对于仅包含一个页面但文件文件中存在多个页面的文件那么它只将文件的第一页转换为图像。有人建议我如何将doc文件的所有页面转换为单独的图像。如何将doc文件的所有页面转换为单独的图像

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 
     Dim objWord As New Microsoft.Office.Interop.Word.Application 
     Dim objDoc As Microsoft.Office.Interop.Word.Document 
     Const CF_ENHMETAFILE As Integer = 14 
     objDoc = objWord.Documents.Open("F:\Study\Constructor.docx") 
     objWord.Activedocument.Select() 
     objWord.Selection.CopyAsPicture() 
     Dim ip As IntPtr 
     Dim metaFile As System.Drawing.Imaging.Metafile 
     Dim bRet As Boolean 
     bRet = ClipboardAPI.OpenClipboard(Me.Handle) 
     If bRet = True Then 
      'Verify the clipboard contains data available 
      'as an enhanced metafile. 
      bRet = ClipboardAPI.IsClipboardFormatAvailable(CF_ENHMETAFILE) <> 0 
     End If 

     If bRet = True Then 
      'Store the clipboard's contents in the IntPtr. 
      ip = ClipboardAPI.GetClipboardData(CF_ENHMETAFILE) 
     End If 

     'Verify the IntPrt contains data before proceeding. Passing 
     'an empty IntPtr to System.Drawing.Imaging.Metafile results 
     'in an exception. 
     If Not IntPtr.Zero.Equals(ip) Then 
      metaFile = New System.Drawing.Imaging.Metafile(ip, True) 
      ClipboardAPI.CloseClipboard() 
      Dim image As System.Drawing.Image = metaFile 
      'Me.PictureBox1.Image = metaFile 

      Dim objImageWriter As Image = New Bitmap(image.Width, image.Height) 

      Dim objGraphics As Graphics = Graphics.FromImage(objImageWriter) 

      objGraphics.Clear(Color.White) 
      'objGraphics.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias 
      objGraphics.DrawImage(image, 0, 0, image.Width, image.Height) 


      image.Dispose() 
      objGraphics.Dispose() 

      Dim ep As Imaging.EncoderParameters = New Imaging.EncoderParameters 
      ep.Param(0) = New System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100) 

      Dim codecs() As Imaging.ImageCodecInfo = Imaging.ImageCodecInfo.GetImageEncoders() 
      Dim iciInfo As Imaging.ImageCodecInfo 
      Dim item As Imaging.ImageCodecInfo 

      For Each item In codecs 
       If (item.MimeType = "image/jpeg") Then iciInfo = item 
      Next 

      objImageWriter.Save("F:\Study\test1.jpg", iciInfo, ep) 
      objImageWriter.Dispose() 


     End If 


Public Class ClipboardAPI 
    <Runtime.InteropServices.DllImport("user32.dll", EntryPoint:="OpenClipboard", SetLastError:=True, ExactSpelling:=True, CallingConvention:=System.Runtime.InteropServices.CallingConvention.StdCall)> _ 
     Public Shared Function OpenClipboard(ByVal hWnd As IntPtr) As Boolean 
    End Function 

    <Runtime.InteropServices.DllImport("user32.dll", EntryPoint:="EmptyClipboard", SetLastError:=True, ExactSpelling:=True, CallingConvention:=System.Runtime.InteropServices.CallingConvention.StdCall)> _ 
    Public Shared Function EmptyClipboard() As Boolean 
    End Function 

    <Runtime.InteropServices.DllImport("user32.dll", EntryPoint:="SetClipboardData", SetLastError:=True, ExactSpelling:=True, CallingConvention:=System.Runtime.InteropServices.CallingConvention.StdCall)> _ 
    Public Shared Function SetClipboardData(ByVal uFormat As Integer, ByVal ByValhWnd As IntPtr) As IntPtr 
    End Function 

    <Runtime.InteropServices.DllImport("user32.dll", EntryPoint:="CloseClipboard", SetLastError:=True, ExactSpelling:=True, CallingConvention:=System.Runtime.InteropServices.CallingConvention.StdCall)> _ 
    Public Shared Function CloseClipboard() As Boolean 
    End Function 

    <Runtime.InteropServices.DllImport("user32.dll", EntryPoint:="GetClipboardData", SetLastError:=True, ExactSpelling:=True, CallingConvention:=System.Runtime.InteropServices.CallingConvention.StdCall)> _ 
    Public Shared Function GetClipboardData(ByVal uFormat As Integer) As IntPtr 
    End Function 

    <Runtime.InteropServices.DllImport("user32.dll", EntryPoint:="IsClipboardFormatAvailable", SetLastError:=True, ExactSpelling:=True, CallingConvention:=System.Runtime.InteropServices.CallingConvention.StdCall)> _ 
     Public Shared Function IsClipboardFormatAvailable(ByVal uFormat As Integer) As Short 
    End Function 
End Class 

回答

1

问题是行“objWord.Activedocument.Select()”引用整个文档而不是文档的单个页面。我加了一下你的代码,以捕捉每一页的内容的图像:

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 
    Dim objWord As New Microsoft.Office.Interop.Word.Application 
    Dim objDoc As Microsoft.Office.Interop.Word.Document 
    Const CF_ENHMETAFILE As Integer = 14 
    objDoc = objWord.Documents.Open("F:\Study\Constructor.docx") 

    objDoc.Repaginate() 
    For i As Integer = 1 To objDoc.ActiveWindow.Panes(1).Pages.Count 
     If i = 1 Then 
      With objWord.ActiveDocument 
       .GoTo(WdGoToItem.wdGoToPage, WdGoToDirection.wdGoToAbsolute, 1) 
       .Bookmarks("\Page").Range.Select() 
      End With 
     Else 
      With objWord.Selection 
       .GoTo(What:=WdGoToItem.wdGoToPage, Which:=WdGoToDirection.wdGoToNext) 
       .Bookmarks("\Page").Range.Select() 
      End With 
     End If 

     objWord.Selection.CopyAsPicture() 
     Dim ip As IntPtr 
     Dim metaFile As System.Drawing.Imaging.Metafile 
     Dim bRet As Boolean 
     bRet = ClipboardAPI.OpenClipboard(Me.Handle) 
     If bRet = True Then 
      'Verify the clipboard contains data available 
      'as an enhanced metafile. 
      bRet = ClipboardAPI.IsClipboardFormatAvailable(CF_ENHMETAFILE) <> 0 
     End If 

     If bRet = True Then 
      'Store the clipboard's contents in the IntPtr. 
      ip = ClipboardAPI.GetClipboardData(CF_ENHMETAFILE) 
     End If 

     'Verify the IntPrt contains data before proceeding. Passing 
     'an empty IntPtr to System.Drawing.Imaging.Metafile results 
     'in an exception. 
     If Not IntPtr.Zero.Equals(ip) Then 
      metaFile = New System.Drawing.Imaging.Metafile(ip, True) 
      ClipboardAPI.CloseClipboard() 
      Dim image As System.Drawing.Image = metaFile 
      'Me.PictureBox1.Image = metaFile 

      Dim objImageWriter As Image = New Bitmap(image.Width, image.Height) 

      Dim objGraphics As Graphics = Graphics.FromImage(objImageWriter) 

      objGraphics.Clear(Color.White) 
      'objGraphics.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias 
      objGraphics.DrawImage(image, 0, 0, image.Width, image.Height) 


      image.Dispose() 
      objGraphics.Dispose() 

      Dim ep As Imaging.EncoderParameters = New Imaging.EncoderParameters 
      ep.Param(0) = New System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 100) 

      Dim codecs() As Imaging.ImageCodecInfo = Imaging.ImageCodecInfo.GetImageEncoders() 
      Dim iciInfo As Imaging.ImageCodecInfo 
      Dim item As Imaging.ImageCodecInfo 

      For Each item In codecs 
       If (item.MimeType = "image/jpeg") Then iciInfo = item 
      Next 

      objImageWriter.Save("F:\Study\test" & i.ToString & ".jpg", iciInfo, ep) 
      objImageWriter.Dispose() 
     End If 
    Next 
End Sub 

的额外的代码变动摘要:

我补充说:“objDoc.Repaginate()”,以获得准确的页面引用。 Word通常并不真正使用页面,它会不断地查询系统的打印驱动程序,以决定将文本分解成页面所需的位置。这确保了我们根据当前机器准确计数页数。

我在这个for-loop中包含了你的图像逻辑:“For I As Integer = 1 To objDoc.ActiveWindow.Panes(1).Pages.Count”。直接在该行之后的if-else将在第一次迭代中选择第一页,然后选择其后的任何后续附加页。除了save-filename之外,其他所有内容都保持不变。

最后,我只是级联页码为明显的原因图像的保存路径...

我测试这是我自己的电脑上,它的工作如预期,我希望这有助于!

...只是一个脱离主题的旁注,我不知道如果处理Word句柄的代码只是没有包括在你的问题中,或者如果它实际上缺少,但你可能想确保你添加那; Interop课程喜欢在后台运行办公室流程,即使在程序关闭后,如果处理不当,这个例子会让他们在我的计算机上打开。

+0

嗨soohoonigan,它完美的作品,并产生预期的结果。非常感谢你。 – Vengat

相关问题