如何验证PDF文件是否“良好”?

时间:2011-07-27 17:40:01

标签: powershell itextsharp

我有一个过程压缩我们的秘书通过在多功能打印机上扫描签名文档而创建的PDF文件。

在极少数情况下,压缩后无法在Acrobat Reader中打开这些文件。我不知道为什么这种情况很少发生,所以我希望能够测试PDF后压缩并看看它是否“好”。

我正在尝试使用itextsharp 5.1.1来完成此任务,但它很乐意加载PDF。我最好的猜测是Acrobat阅读器在尝试显示图片时失败。

关于如何判断PDF是否会呈现的任何想法?

5 个答案:

答案 0 :(得分:3)

在过去的类似情况中,我已成功使用PDF Toolkit (a/k/a pdftk)使用如下命令修复错误的PDF:pdftk broken.pdf output fixed.pdf

答案 1 :(得分:3)

好的,我最终做的是使用itextsharp循环遍历所有流对象并检查它们的长度。我遇到的错误情况是长度为零。这个测试似乎非常可靠。它可能对每个人都不起作用,但它在这种特殊情况下起作用。

答案 2 :(得分:1)

qpdf 将对您的需求有很大帮助:

apt-get install qpdf

qpdf --check filename.pdf

示例输出:

checking filename.pdf
PDF Version: 1.4
File is not encrypted
File is not linearized
WARNING: filename.pdf: file is damaged
WARNING: filename.pdf (object 185 0, file position 1235875): expected n n obj
WARNING: filename.pdf: Attempting to reconstruct cross-reference table
WARNING: filename.pdf: object 185 0 not found in file after regenerating cross reference table
operation for Dictionary object attempted on object of wrong type

答案 3 :(得分:1)

PdfCpu 效果很好。轻松示例:

pdfcpu validate goggles.pdf

严格的例子:

pdfcpu validate -m strict goggles.pdf

https://pdfcpu.io/core/validate

答案 4 :(得分:0)

我已经使用了" pdfinfo.exe"从xpdfbin-win包和cpdf.exe检查PDF文件是否有损坏,但如果没有必要,我们不想涉及二进制文件。

我读到最新的PDF格式最后有一个可读的xml数据目录,所以我使用常规窗口NOTEPAD.exe打开PDF并向下滚动到不可读的数据到最后并看到几个可读的键。我只需要一个键,但选择使用CreationDate和ModDate。

以下Powershell(PS)脚本将检查当前目录中的所有PDF文件,并将每个文件的状态输出到文本文件(!RESULTS.log)中。花了大约2分钟来对抗35,000个PDF文件。我试图为刚接触PS的人添加评论。希望这能节省一些时间。这可能是一种更好的方法,但这可以完美地用于我的目的,并且可以无声地处理错误。您可能需要在开头定义以下内容:$ ErrorActionPreference =" SilentlyContinue"如果你在屏幕上看到错误。

将以下内容复制到文本文件中并正确命名(例如:CheckPDF.ps1)或打开PS并浏览到包含PDF文件的目录,以检查并将其粘贴到控制台中。

#
# PowerShell v4.0
#
# Get all PDF files in current directory
#
$items = Get-ChildItem | Where-Object {$_.Extension -eq ".pdf"}

$logFile = "!RESULTS.log"
$badCounter = 0
$goodCounter = 0
$msg = "`n`nProcessing " + $items.count + " files... "
Write-Host -nonewline -foregroundcolor Yellow $msg
foreach ($item in $items)
{
    #
    # Suppress error messages
    #
    trap { Write-Output "Error trapped"; continue; }

    #
    # Read raw PDF data
    #
    $pdfText = Get-Content $item -raw

    #
    # Find string (near end of PDF file), if BAD file, ptr will be undefined or 0
    #
    $ptr1 = $pdfText.IndexOf("CreationDate")
    $ptr2 = $pdfText.IndexOf("ModDate")

    #
    # Grab raw dates from file - will ERR if ptr is undefined or 0
    #
    try { $cDate = $pdfText.SubString($ptr1, 37); $mDate = $pdfText.SubString($ptr2, 31); }

    #
    # Append filename and bad status to logfile and increment a counter
    # catch block is also where you would rename, move, or delete bad files.
    #
    catch { "*** $item is Broken ***" >> $logFile; $badCounter += 1; continue; }

    #
    # Append filename and good status to logfile
    #
    Write-Output "$item - OK" -EA "Stop" >> $logFile

    #
    # Increment a counter
    #
    $goodCounter += 1
}
#
# Calculate total
#
$totalCounter = $badCounter + $goodCounter

#
# Append 3 blank lines to end of logfile
#
1..3 | %{ Write-Output "" >> $logFile }

#
# Append statistics to end of logfile
#
Write-Output "Total: $totalCounter / BAD: $badCounter / GOOD: $goodCounter" >> $logFile
Write-Output "DONE!`n`n"