PDF 文档的页数不一致
Inconsistent page count of a PDF document
我正在尝试获取 PDF 文档中的页数。我的一些 PDF 是在 Word 中创建的(另存为 PDF),其中一些是复印到目录中的(不确定这是否重要)。
经过数小时的研究,我发现这说起来容易做起来难。 页数很少返回给我正确的页数,尽管实际上大多数 PDF 的二进制代码中确实有 /Count
。
例如我使用了以下代码;它应该以二进制模式打开文档,查找 /Count
或 /N
并获取它旁边的数字,它应该给我页数。
Public Sub pagecount(sfilename As String)
On Error GoTo a
Dim nFileNum As Integer
Dim s As String
Dim c As Integer
Dim pos, pos1 As Integer
pos = 0
pos1 = 0
c = 0
' Get an available file number from the system
nFileNum = FreeFile
'OPEN the PDF file in Binary mode
Open sfilename For Binary Lock Read Write As #nFileNum
' Get the data from the file
Do Until EOF(nFileNum)
Input #1, s
c = c + 1
If c <= 10 Then
pos = InStr(s, "/N")
End If
pos1 = InStr(s, "/count")
If pos > 0 Or pos1 > 0 Then
Close #nFileNum
s = Trim(Mid(s, pos, 10))
s = Replace(s, "/N", "")
s = Replace(s, "/count", "")
s = Replace(s, " ", "")
s = Replace(s, "/", "")
For i = 65 To 125
s = Replace(s, Chr(i), "")
Next
pages = Val(Trim(s))
If pages < 0 Then
pages = 1
End If
Close #nFileNum
Exit Sub
End If
'imp only 1000 lines searches
If c >= 1000 Then
GoTo a
End If
Loop
Close #nFileNum
Exit Sub
a:
Close #nFileNum
pages = 1
Exit Sub
End Sub
然而,大多数时候,它默认为 pages = 1(在 a: 下)。
我还将其更新为 10000 以确保它达到 /Count
行,但它仍然没有给我正确的计数。
If c >= 10000 Then
GoTo a
End If
我也遇到了这个reddit
有没有其他方法可以做到这一点,我可以在我的应用程序中使用?
非常感谢任何帮助。
背景:
这是我试图让用户操作 PDF 文件的旧版 vb6 应用程序。我添加了一个列表框,用于显示特定目录中的所有 PDF 文档。当用户双击任何一个文件时,我会在我的应用程序内的 WebBrowser 组件中显示它。
编辑:图像包含 3 个不同文档的 BinaryMode 行计数:
我仔细检查了页数,/Count 显示了三个文档中每一个的正确页数。
正则表达式有限制,但我更喜欢用它们来搜索字符串,我认为这是使用正则表达式的好地方。您可能想尝试一下该模式,因为我只进行了一些测试就相对快速地完成了这项工作。
将对 Microsoft VBScript Regular Expressions 5.5 的引用添加到您的项目中。那么您可以试试下面的示例代码。
Private Sub Command1_Click()
Dim oRegEx As RegExp
Dim fHndl As Integer
Dim sContents As String
Dim oMatches As MatchCollection
On Error GoTo ErrCommand1_Click
'Open and read in the file
fHndl = FreeFile
Open some pdf file For Binary Access Read As fHndl
sContents = String(LOF(fHndl), vbNull)
Get #fHndl, 1, sContents
Close #fHndl 'We have the file contents so close it
fHndl = 0
'Instantiate and configure the RegEx
Set oRegEx = New RegExp
oRegEx.Global = True
oRegEx.Pattern = "((?:/Count )(\d+))"
Set oMatches = oRegEx.Execute(sContents)
'Look for a match
If oMatches.Count > 0 Then
If oMatches(0).SubMatches.Count > 0 Then
MsgBox CStr(oMatches(0).SubMatches(0)) & " Pages"
End If
End If
Exit Sub
ErrCommand1_Click:
Debug.Print "Error: " & CStr(Err.Number) & ", " & Err.Description
If Not oRegEx Is Nothing Then Set oRegEx = Nothing
If Not oMatches Is Nothing Then Set oMatches = Nothing
End Sub
RegEx 模式的解释:
()
创建一个群组
?:
括号内使组非捕获
<</Linearized
是文字字符串
.*
贪心量词,匹配任意字符0次或多次
/N
文字字符串
\d+
贪婪限定符,匹配数字1次或多次
>>
文字字符串
我正在尝试获取 PDF 文档中的页数。我的一些 PDF 是在 Word 中创建的(另存为 PDF),其中一些是复印到目录中的(不确定这是否重要)。
经过数小时的研究,我发现这说起来容易做起来难。 页数很少返回给我正确的页数,尽管实际上大多数 PDF 的二进制代码中确实有 /Count
。
例如我使用了以下代码;它应该以二进制模式打开文档,查找 /Count
或 /N
并获取它旁边的数字,它应该给我页数。
Public Sub pagecount(sfilename As String)
On Error GoTo a
Dim nFileNum As Integer
Dim s As String
Dim c As Integer
Dim pos, pos1 As Integer
pos = 0
pos1 = 0
c = 0
' Get an available file number from the system
nFileNum = FreeFile
'OPEN the PDF file in Binary mode
Open sfilename For Binary Lock Read Write As #nFileNum
' Get the data from the file
Do Until EOF(nFileNum)
Input #1, s
c = c + 1
If c <= 10 Then
pos = InStr(s, "/N")
End If
pos1 = InStr(s, "/count")
If pos > 0 Or pos1 > 0 Then
Close #nFileNum
s = Trim(Mid(s, pos, 10))
s = Replace(s, "/N", "")
s = Replace(s, "/count", "")
s = Replace(s, " ", "")
s = Replace(s, "/", "")
For i = 65 To 125
s = Replace(s, Chr(i), "")
Next
pages = Val(Trim(s))
If pages < 0 Then
pages = 1
End If
Close #nFileNum
Exit Sub
End If
'imp only 1000 lines searches
If c >= 1000 Then
GoTo a
End If
Loop
Close #nFileNum
Exit Sub
a:
Close #nFileNum
pages = 1
Exit Sub
End Sub
然而,大多数时候,它默认为 pages = 1(在 a: 下)。
我还将其更新为 10000 以确保它达到 /Count
行,但它仍然没有给我正确的计数。
If c >= 10000 Then
GoTo a
End If
我也遇到了这个reddit
有没有其他方法可以做到这一点,我可以在我的应用程序中使用?
非常感谢任何帮助。
背景:
这是我试图让用户操作 PDF 文件的旧版 vb6 应用程序。我添加了一个列表框,用于显示特定目录中的所有 PDF 文档。当用户双击任何一个文件时,我会在我的应用程序内的 WebBrowser 组件中显示它。
编辑:图像包含 3 个不同文档的 BinaryMode 行计数:
我仔细检查了页数,/Count 显示了三个文档中每一个的正确页数。
正则表达式有限制,但我更喜欢用它们来搜索字符串,我认为这是使用正则表达式的好地方。您可能想尝试一下该模式,因为我只进行了一些测试就相对快速地完成了这项工作。
将对 Microsoft VBScript Regular Expressions 5.5 的引用添加到您的项目中。那么您可以试试下面的示例代码。
Private Sub Command1_Click()
Dim oRegEx As RegExp
Dim fHndl As Integer
Dim sContents As String
Dim oMatches As MatchCollection
On Error GoTo ErrCommand1_Click
'Open and read in the file
fHndl = FreeFile
Open some pdf file For Binary Access Read As fHndl
sContents = String(LOF(fHndl), vbNull)
Get #fHndl, 1, sContents
Close #fHndl 'We have the file contents so close it
fHndl = 0
'Instantiate and configure the RegEx
Set oRegEx = New RegExp
oRegEx.Global = True
oRegEx.Pattern = "((?:/Count )(\d+))"
Set oMatches = oRegEx.Execute(sContents)
'Look for a match
If oMatches.Count > 0 Then
If oMatches(0).SubMatches.Count > 0 Then
MsgBox CStr(oMatches(0).SubMatches(0)) & " Pages"
End If
End If
Exit Sub
ErrCommand1_Click:
Debug.Print "Error: " & CStr(Err.Number) & ", " & Err.Description
If Not oRegEx Is Nothing Then Set oRegEx = Nothing
If Not oMatches Is Nothing Then Set oMatches = Nothing
End Sub
RegEx 模式的解释:
()
创建一个群组
?:
括号内使组非捕获
<</Linearized
是文字字符串
.*
贪心量词,匹配任意字符0次或多次
/N
文字字符串
\d+
贪婪限定符,匹配数字1次或多次
>>
文字字符串