Excel VBA从受保护的PDF文件返回页数

时间:2018-01-28 09:23:00

标签: vba excel-vba pdf text-extraction excel

我需要使用Excel VBA检索PDF文件中的页数(使用安全性)。

以下代码在PDF文件中启用 no 安全性时起作用:

Sub PDFandNumPages()

   Dim Folder As Object
   Dim file As Object
   Dim fso As Object
   Dim iExtLen As Integer, iRow As Integer
   Dim sFolder As String, sExt As String
   Dim sPDFName As String

   sExt = "pdf"
   iExtLen = Len(sExt)
   iRow = 1
   ' Must have a '\' at the end of path
   sFolder = "C:\test\"

   Set fso = CreateObject("Scripting.FileSystemObject")

   If sFolder <> "" Then
      Set Folder = fso.GetFolder(sFolder)
      For Each file In Folder.Files
         If Right(file, iExtLen) = sExt Then
            Cells(iRow, 1).Value = file.Name
            Cells(iRow, 2).Value = pageCount(sFolder & file.Name)
            iRow = iRow + 1
         End If
      Next file
   End If

End Sub

但是,如果启用了任何类型的安全性,则代码无法提取页码&amp;返回零页面。

Property of PDF file with some kind of security

注意:没有密码保护来打开这些PDF文件,它只启用了一些安全功能来阻止PDF的修改

启用安全性的示例PDF可在以下Google云端硬盘链接中找到:Google Drive PDF with security

我的要求是调整代码,以便显示PDF文件中的页码是否有任何安全性。

对于Python,我发现了一个类似的问题&amp;解决方案在this page,但它使用Python库。如果可能的话,我希望VBA方面的专家建议我如何在VBA中复制它

1 个答案:

答案 0 :(得分:0)

如果PDF文档 没有权限密码设置(或者您知道密码),则可以修改文档限制,例如页面提取。< / p>

  • 使用专有或第三方编辑器手动打开文档
  • 转到FileProperties
  • Security标签中,选择Show Details…

Doc Properties

  • 要更改PDF的限制,请转到视图→工具→保护
  • 工具窗格中,点击Encrypt,然后在Protection部分中选择Remove Security
  • 如果有权限密码,则需要在此处输入。

权限现在将更改为“允许”

Permissions Source

“Hacky”方法:

如果上述方法对您不起作用,可以采用一种解决方法。您本身不会解锁文件本身,但您可以生成一个解锁的等效文件,可以根据您的内容进行编辑和操作。

  • Adobe Acrobat Reader
  • 中打开要解锁的文档
  • 点击File,然后点击Print
  • 打印机列表中,选择"Microsoft XPS Document Writer",然后点击打印

如果您尝试使用Adobe的PDF打印机驱动程序,它会检测到您正在尝试将安全的PDF导出到新文件,它将拒绝继续。即使是第三方PDF打印驱动程序也会扼杀这些文件。

但是,通过使用 XPS Document Writer ,您可以有效地绕过该检查,为您留下XPS输出。

  • 打开刚刚创建的新XPS文件,只需重复打印过程,这次打印为PDF格式

如果您没有在打印机列表中选择PDF打印机,则可以在线获得各种免费软件选项(例如CutePDF Writer),这样您就可以设置生成PDF的虚拟打印机。 <子>(Source

修改(替代答案)

返回PDF文件的页数

要在VBA中查找PDF文件中的总页数,您可以将其打开为二进制文件,然后解析文件,查找“/Count”,然后阅读随后的数字。

以下示例适用于您的示例文件(6和8页),但可能需要“调整”,具体取决于手头各个PDF文件的结构。

(在某些情况下,您可能最好计算/Page”或“/Pages”标签的各个匹配项,尽管这个数字可能需要将减少 1或2。)

请注意,这是解析二进制文件的一种非常有效的方法,因此大文件可能需要一段时间才能解析。

Sub Get_PDF_Page_Count()
'scrape PDF file as binary, looking for "/Count" tag, then return the number following it
    Const fName = "C:\your_path_here\1121-151134311859-64.pdf"
    Dim bytTemp As Byte, fileStr As String, c As Long, p1 As Long, p2 As Long

    'open PDF as binary file
    Debug.Print "Reading File '" & fName & "'";
    Open fName For Binary Access Read As #1

    'read file into string
    Do While Not EOF(1)

        'parse PDF file, one byte at a time
        Get #1, , bytTemp
        c = c + 1
        fileStr = fileStr & Chr(bytTemp)

        'check every 20000 characters, if the tag was found yet
        If c / 20000 = c \ 20000 Then
            If InStr(fileStr, "/Count") > 0 Then Exit Do
            ' not found yet, keep going
            Debug.Print ".";
            DoEvents
        End If
    Loop

    'close file
    Close #1
    Debug.Print

    'check if tag was found
    If InStr(fileStr, "/Count") = 0 Then
        Debug.Print "'/Count' tag not found in file: " & fName
        Exit Sub
    End If

    'return page count
    p1 = InStr(fileStr, "/Count")
    p1 = InStr(p1, fileStr, " ") + 1
    p2 = InStr(p1, fileStr, vbLf)
    Beep
    Debug.Print Val(Mid(fileStr, p1, p2 - p1)) & " pages in file: " & fName

End Sub