以编程方式填写浏览器控件中的PDF表单字段

时间:2012-02-04 06:24:28

标签: c# javascript vb.net forms pdf

基本方案是我需要以编程方式填写驻留在网络服务器上的PDF文本字段。将使用CSV中包含的数据映射和填写字段。必须在浏览器中打开PDF(浏览器控件或ie / ff / chrome / etc)并进行编辑。无法下载,填写和上传(必须使用其中的提交按钮填写和提交;我已尝试编辑按钮提交路径无效)。

到目前为止,我已经在表单上放置了一个Web浏览器控件,并使其导航到网站,登录并加载PDF文件。如何与Web浏览器控件中打开的PDF文件进行交互?通过查看各种PDF库,它们似乎主要与位于硬盘上的已关闭pdf进行交互,进行修改并重新保存。

编辑:我对替代解决方案非常开放。我不知道它是否可能,但如果是这样的话 - 在我的机器上运行基于PDF的javascript,我在表单上运行?如果我下载它,我可以很容易地做到这一点,但似乎无法在webbrowser中打开时使用PDFJS。

2 个答案:

答案 0 :(得分:2)

我担心做你想做的事情并不容易。首先,您必须找到嵌入在WebBrowser控件中的PDF阅读器的窗口句柄。以下是如何执行此操作的示例代码:

    Public Function GetPdfViewerHandle() As System.IntPtr
    Dim tempHandle As System.IntPtr
    '--------------------------------------
    ' get handle to pdf viewer
    '--------------------------------------
    '--------------------------------------
    ' first check for the foxit reader
    '--------------------------------------
    tempHandle = FindChildWindow(WebBrowser1.Handle, "AfxWnd42s", "Reader", 1, True)
    If IntPtr.Zero.Equals(tempHandle) = True Then
        '---------------------------------
        ' if not foxit, check for adobe
        '---------------------------------
        tempHandle = FindChildWindow(WebBrowser1.Handle, "AVL_AVVIEW", "AVPageView", 1, True)
    End If

    Return tempHandle

End Function

Public Shared Function FindChildWindow(ByVal hParent As IntPtr, ByVal P_childClass As String, ByVal P_childTitle As String, ByVal P_count As Integer, ByVal p_recursive As Boolean) As IntPtr
     Dim hChild As IntPtr
     Dim className As String
     Dim title As String
     Dim cnt As Integer
     Dim tempPtr As IntPtr
     Dim Declare Function FindWindowExA Lib "user32.dll" (ByVal hWnd1 As IntPtr, ByVal hWnd2 As Int32, ByVal lpsz1 As String, ByVal lpsz2 As String) As IntPtr

     cnt = 0

     hChild = FindWindowExA(hParent, 0, Nothing, Nothing)

     While hChild.ToInt32 > 0

        If P_childClass Is Nothing Then
           className = GetClassName(hChild)
        Else
           className = GetClassName(hChild)
           If P_childClass.Length < className.Length Then
              className = className.Substring(0, P_childClass.Length)
           End If
        End If

        If P_childTitle Is Nothing Then
           title = GetWindowText(hChild).Replace("&", "")
        Else
           title = GetWindowText(hChild).Replace("&", "")

           If P_childTitle.Length < title.Length Then
              title = title.Substring(0, P_childTitle.Length)
           End If
        End If


        Debug.WriteLine("hwnd=" + Hex$(hChild.ToInt32) + ", className = " + className + ", title = " + title)
        If (String.Compare(className, P_childClass, True) = 0 And String.Compare(title, P_childTitle, True) = 0) Or (P_childClass = Nothing And String.Compare(title, P_childTitle, True) = 0) Or (String.Compare(className, P_childClass, True) = 0 And P_childTitle = Nothing) Then
           cnt += 1
           If cnt >= P_count Then
              Return hChild
           End If
        End If

        If p_recursive = True Then
           tempPtr = FindChildWindow(hChild, P_childClass, P_childTitle, 1, p_recursive)
           If IntPtr.Zero.Equals(tempPtr) = False Then
              Return tempPtr
           End If
        End If

        hChild = FindWindowExA(hParent, hChild.ToInt32, Nothing, Nothing)
     End While

     Return Nothing

  End Function

一旦有了窗口句柄,就会有很多不同的方法来查找表单字段。如果你知道事情的顺序,你可以简单地开始向pdf阅读器句柄发送键命令或使用Spy ++找到表单字段的句柄,通过Win32Api SendMessageA函数向它们输入数据:

      Public Declare Function SendMessageA Lib "user32.dll" (ByVal hwnd As IntPtr, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer

                  asciiChar = CByte(Asc(data.Substring(0, 1)))
              rc = SendMessageA(hwnd, WM_CHAR, asciiChar, 0)    
祝你好运。

答案 1 :(得分:0)

如果您必须通过PDF上的按钮提交数据,只需检查提交的流量并查看它发送的内容,然后您就可以使用VB.NET进行复制,甚至不必加载PDF文档。