0

我想知道是否有人知道让 .pdf 文件在加载时触发就绪状态的简单方法。我正在构建一个程序来打开 url 并截取屏幕截图,然后将它们放入 excel 中。

While Not pagereadyWeb 浏览器会正确加载 html 文档,但在加载.pdf文件时会卡住。浏览器控件正确呈现.pdf.

Private Sub btngo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btngo.Click
    Dim file As String
    Dim Obj As New Object
    Dim result As String
    Dim sheet As String = "sheet1"
    Dim xlApp As New Excel.Application

    If lblpath.Text <> "" Then
        file = lblpath.Text
        Dim xlWorkBook = xlApp.Workbooks.Open(file)
        Dim xlWorkSheet = xlWorkBook.Worksheets(sheet)
        Dim range = xlWorkSheet.UsedRange

        ProgressBar1.Value = 0

        For rCnt = 4 To range.Rows.Count
            'url cell
            Obj = CType(range.Cells(rCnt, 2), Excel.Range)
            ' Obj.value now contains the value in the cell.. 
            Try
                ' Creates an HttpWebRequest with the specified URL. 
                Dim myHttpWebRequest As HttpWebRequest = CType(WebRequest.Create(Obj.value), HttpWebRequest)
                ' Sends the request and waits for a response. 
                Dim myHttpWebResponse As HttpWebResponse = CType(myHttpWebRequest.GetResponse(), HttpWebResponse)
                If myHttpWebResponse.StatusCode = HttpStatusCode.OK Then
                    result = myHttpWebResponse.StatusCode
                    WebBrowser1.ScrollBarsEnabled = False
                    WebBrowser1.Navigate(myHttpWebRequest.RequestUri)

                    WaitForPageLoad()

                    CaptureWebBrowser(WebBrowser1)
                End If
                ' Release the resources of the response.
                myHttpWebResponse.Close()

            Catch ex As WebException
                result = (ex.Message)
            Catch ex As Exception
                result = (ex.Message)
            End Try


            RichTextBox1.AppendText(result & "    " & Obj.value & vbNewLine)

            If radpre.Checked = True Then
                range.Cells(rCnt, 3).value = result
            ElseIf radcob.Checked = True Then
                range.Cells(rCnt, 4).value = result
            ElseIf radpost.Checked = True Then
                range.Cells(rCnt, 5).value = result

            End If


            ProgressBar1.Value = rCnt / range.Rows.Count * 100
        Next

        With xlApp
            .DisplayAlerts = False
            xlWorkBook.SaveAs(lblpath.Text.ToString)
            .DisplayAlerts = True
        End With

        xlWorkBook.Close()
        xlApp.Quit()

        'reclaim memory
        Marshal.ReleaseComObject(xlApp)
        xlApp = Nothing
    End If
End Sub

Private Function CaptureWebBrowser(ByVal wb As WebBrowser) As Image
    Try
        Dim hBitmap As Bitmap = New Bitmap(wb.Width, wb.Height)
        wb.DrawToBitmap(hBitmap, wb.Bounds)
        Dim img As Image = hBitmap
        Return img
    Catch ex As Exception
        MessageBox.Show(ex.Message)
    End Try
    Return Nothing
End Function


Private Sub WaitForPageLoad()
    AddHandler WebBrowser1.DocumentCompleted, New WebBrowserDocumentCompletedEventHandler(AddressOf PageWaiter)
    While Not pageready
        Application.DoEvents()
    End While
    pageready = False
End Sub

Private Sub PageWaiter(ByVal sender As Object, ByVal e As WebBrowserDocumentCompletedEventArgs)
    If WebBrowser1.ReadyState = WebBrowserReadyState.Complete Then
        pageready = True
        RemoveHandler WebBrowser1.DocumentCompleted, New WebBrowserDocumentCompletedEventHandler(AddressOf PageWaiter)
    End If
End Sub

更新到已解决


我对反馈感到非常满意。我真的很喜欢Noseratio提供的答案。我不知道使用代码模式不是最佳实践。打开 .pdf 或任何其他非基于 Web 的文档readyState时,将永远不会从 .pdf 更改0。看到这个程序只是我不工作的一种方式,我对只捕获.html.htm.

我的要求是

  1. 打开excel文档
  2. 解析位于 excel 文档中的链接
  3. 确定响应代码
  4. 编写响应代码,如果可能的话,截图到 excel

该程序解析和检索反馈的速度比我手动完成的要快得多。成功从生产环境迁移到 COB 并返回生产环境的 excel 文件证明的屏幕截图.html.htm提供非技术查看者。

Noseratio所述的代码不遵循最佳实践,也不是高质量的。这是一个快速而肮脏的实现。

Option Infer On
Imports Microsoft.Office.Interop
Imports System.Net
Imports System.Runtime.InteropServices

Public Class Form1


Public Property pageready As Boolean

Private Sub OpenToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OpenToolStripMenuItem.Click
    OpenFileDialog1.ShowDialog()
End Sub

Private Sub OpenFileDialog1_FileOk(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles OpenFileDialog1.FileOk
    lblpath.Text = OpenFileDialog1.FileName.ToString
End Sub

Private Sub btngo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btngo.Click
    Dim file As String
    Dim Obj As New Object
    Dim result As String
    Dim sheet As String = "sheet1"
    Dim xlApp As New Excel.Application
    Dim img As Bitmap
    Dim path As String = "C:\Documents and Settings\user\My Documents\Visual Studio 2010\Projects\COB-HTML-Tool\COB-HTML-Tool\bin\Debug\tmp.bmp"
    If lblpath.Text <> "" Then
        file = lblpath.Text
        Dim xlWorkBook = xlApp.Workbooks.Open(file)
        Dim xlWorkSheet = xlWorkBook.Worksheets(sheet)
        Dim range = xlWorkSheet.UsedRange

        ProgressBar1.Value = 0

        For rCnt = 4 To range.Rows.Count
            'url cell
            Obj = CType(range.Cells(rCnt, 2), Excel.Range)
            ' Obj.value now contains the value in the cell.. 
            Try
                ' Creates an HttpWebRequest with the specified URL. 
                Dim myHttpWebRequest As HttpWebRequest = CType(WebRequest.Create(Obj.value), HttpWebRequest)
                ' Sends the request and waits for a response. 
                Dim myHttpWebResponse As HttpWebResponse = CType(myHttpWebRequest.GetResponse(), HttpWebResponse)
                If myHttpWebResponse.StatusCode = HttpStatusCode.OK Then
                    result = myHttpWebResponse.StatusCode


                    Dim len As Integer = myHttpWebRequest.RequestUri.ToString.Length - 4
                    If myHttpWebRequest.RequestUri.ToString.Substring(len) = ".htm" Or
                        myHttpWebRequest.RequestUri.ToString.Substring(len - 1) = ".html" Or
                        myHttpWebRequest.RequestUri.ToString.Substring(len) = ".asp" Then
                        WebBrowser1.Navigate(myHttpWebRequest.RequestUri)
                        WaitForPageLoad()

                        img = CaptureWebBrowser(WebBrowser1)
                        img.Save(path)
                    End If

                End If
    ' Release the resources of the response.
    myHttpWebResponse.Close()

            Catch ex As WebException
        result = (ex.Message)
    Catch ex As Exception
        result = (ex.Message)
    End Try


            RichTextBox1.AppendText(result & "    " & Obj.value & vbNewLine)

            If radpre.Checked = True Then
                range.Cells(rCnt, 3).value = result

                If img Is Nothing Then
                Else
                    If Dir(path) <> "" Then
                        range.Cells(rCnt, 4).Select()
                        Dim opicture As Object
                        opicture = xlApp.ActiveSheet.Pictures.Insert(path)
                        opicture.ShapeRange.LockAspectRatio = True
                        opicture.ShapeRange.width = 170
                        opicture.ShapeRange.height = 170
                        My.Computer.FileSystem.DeleteFile(path)

                    End If
                End If
            ElseIf radcob.Checked = True Then
                range.Cells(rCnt, 5).value = result
                If img Is Nothing Then
                Else
                    If Dir(path) <> "" Then
                        range.Cells(rCnt, 6).Select()
                        Dim opicture As Object
                        opicture = xlApp.ActiveSheet.Pictures.Insert(path)
                        opicture.ShapeRange.LockAspectRatio = True
                        opicture.ShapeRange.width = 170
                        opicture.ShapeRange.height = 170
                        My.Computer.FileSystem.DeleteFile(path)
                    End If
                End If
            ElseIf radpost.Checked = True Then
                range.Cells(rCnt, 7).value = result
                If img Is Nothing Then
                Else
                    If Dir(path) <> "" Then
                        range.Cells(rCnt, 8).Select()
                        Dim opicture As Object
                        opicture = xlApp.ActiveSheet.Pictures.Insert(path)
                        opicture.ShapeRange.LockAspectRatio = True
                        opicture.ShapeRange.width = 170
                        opicture.ShapeRange.height = 170
                        My.Computer.FileSystem.DeleteFile(path)
                    End If
                End If
            End If


            ProgressBar1.Value = rCnt / range.Rows.Count * 100
        Next

        With xlApp
            .DisplayAlerts = False
            xlWorkBook.SaveAs(lblpath.Text.ToString)
            .DisplayAlerts = True
        End With

        xlWorkBook.Close()
        xlApp.Quit()

        'reclaim memory
        Marshal.ReleaseComObject(xlApp)
        xlApp = Nothing
    End If
End Sub
Private Function CaptureWebBrowser(ByVal wb As WebBrowser) As Image

    Try
        wb.ScrollBarsEnabled = False
        Dim hBitmap As Bitmap = New Bitmap(wb.Width, wb.Height)
        wb.DrawToBitmap(hBitmap, wb.Bounds)
        Dim img As Image = hBitmap
        Return img
    Catch ex As Exception
        MessageBox.Show(ex.Message)
    End Try
    Return Nothing
End Function


Private Sub WaitForPageLoad()
    AddHandler WebBrowser1.DocumentCompleted, New WebBrowserDocumentCompletedEventHandler(AddressOf PageWaiter)
    While Not pageready
        Application.DoEvents()
        System.Threading.Thread.Sleep(200)
    End While
    pageready = False
End Sub

Private Sub PageWaiter(ByVal sender As Object, ByVal e As WebBrowserDocumentCompletedEventArgs)
    If WebBrowser1.ReadyState = WebBrowserReadyState.Complete Then
        pageready = True
        RemoveHandler WebBrowser1.DocumentCompleted, New WebBrowserDocumentCompletedEventHandler(AddressOf PageWaiter)
    End If
End Sub


End Class
4

1 回答 1

0

不幸的是,您将无法webBrowser.DrawToBitmap获得 PDF 视图的快照。在撰写本文时,Adobe Acrobat Reader ActiveX 控件不支持在自定义设备上下文上呈现,因此此方法将不起作用,也无法通过 WebBrowser 直接在 Reader ActiveX 对象上发送WM_PRINT或调用(我IViewObject::Draw试过了,我并不孤单)。正确的解决方案是使用第 3 方 PDF 渲染组件。

附带说明一下,您应该避免使用这样的代码模式:

While Not pageready
    Application.DoEvents()
End While

这是一个忙于等待的紧密循环,徒劳地消耗 CPU 周期。至少,将一些Thread.Sleep(200)内容放入循环中,但总的来说,您也应该避免使用 Application.DoEvents

于 2013-09-11T06:57:19.857 回答