gpt4 book ai didi

powershell - 在Powershell中使用itextsharp从PDF提取页面

转载 作者:行者123 更新时间:2023-12-03 00:43:56 25 4
gpt4 key购买 nike

我已经对此进行了数周的研究,但似乎在这个问题上没有取得太大进展。我有一个很大的PDF(超过900页),这是邮件合并的结果。结果是同一文档的900多个副本(一页),唯一的不同是在底部有一个人的名字。我要执行的操作是让Powershell脚本使用itextsharp读取文档并将包含特定字符串(人名)的页面保存到各自的文件夹中。

到目前为止,这是我所设法完成的。

Add-Type -Path C:\scripts\itextsharp.dll

$reader = New-Object iTextSharp.text.pdf.pdfreader -ArgumentList
"$pwd\downloads\TMs.pdf"
for($page = 1; $page -le $reader.NumberOfPages; $page++) {


$pageText = [iTextSharp.text.pdf.parser.PdfTextExtractor]::GetTextFromPage($reader,$page).Split([char]0x000A)

if($PageText -match 'DAN KAGAN'){
Write-Host "DAN FOUND"
}
}

如您所见,我现在仅使用一个名称进行测试。该脚本会正确找到该名称10次。我似乎找不到任何信息,是如何提取此字符串显示在其上的页面。

我希望这是清楚的。如果可以提供帮助,请告诉我。

谢谢!

最佳答案

我实际上刚写完一个非常相似的脚本。使用我的脚本,我需要扫描报告卡的PDF,找到学生的姓名和身份证号,然后提取该页面并适当命名。但是,每个报告卡可以跨越多个页面。

看来您使用的是iTextSharp 5,它很好,因为我也是如此。iTextSharp7的语法完全不同,我还没有学过。

大致来说,这是进行页面提取的逻辑:

    $Document = [iTextSharp.text.Document]::new($PdfReader.GetPageSizeWithRotation($StartPage))
$TargetMemoryStream = [System.IO.MemoryStream]::new()
$PdfCopy = [iTextSharp.text.pdf.PdfSmartCopy]::new($Document, $TargetMemoryStream)

$Document.Open()
foreach ($Page in $StartPage..$EndPage) {
$PdfCopy.AddPage($PdfCopy.GetImportedPage($PdfReader, $Page));
}
$Document.Close()

$NewFileName = 'Elementary Student Record - {0}.pdf' -f $Current.Student_Id
$NewFileFullName = [System.IO.Path]::Combine($OutputFolder, $NewFileName)
[System.IO.File]::WriteAllBytes($NewFileFullName, $TargetMemoryStream.ToArray())

这是完整的工作脚本。我删除了尽可能少的内容,为您提供了一个可行的示例:
Import-Module -Name SqlServer -Cmdlet Invoke-Sqlcmd
Add-Type -Path 'C:\...\itextsharp.dll'

# Get table of valid student IDs
$ServerInstance = '...'
$Database = '...'
$Query = @'
select student_id, student_name from student
'@
$ValidStudents = @{}
Invoke-Sqlcmd -Query $Query -ServerInstance $ServerInstance -Database $Database -OutputAs DataRows | ForEach-Object {
[void]$ValidStudents.Add($_.student_id.trim(), $_.student_name)
}

$PdfFiles = Get-ChildItem "G:\....\*.pdf" -File |
Select-Object -ExpandProperty FullName
$OutputFolder = 'G:\...'

$StudentIDSearchPattern = '(?mn)^(?<Student_Id>\d{6,7}) - (?<Student_Name>.*)$'
foreach ($PdfFile in $PdfFiles) {
$PdfReader = [iTextSharp.text.pdf.PdfReader]::new($PdfFile)

$StudentStack = [System.Collections.Stack]::new()

# Map out the PDF file.
foreach ($Page in 1..($PdfReader.NumberOfPages)) {
[iTextSharp.text.pdf.parser.PdfTextExtractor]::GetTextFromPage($PdfReader, $Page) |
Where-Object { $_ -match $StudentIDSearchPattern } |
ForEach-Object {
$StudentStack.Push([PSCustomObject]@{
Student_Id = $Matches['Student_Id']
Student_Name = $Matches['Student_Name']
StartPage = $Page
IsValid = $ValidStudents.ContainsKey($Matches['Student_Id'])
})
}
}

# Extract the pages and save the files
$LastPage = $PdfReader.NumberOfPages
while ($StudentStack.Count -gt 0) {
$Current = $StudentStack.Pop()

$StartPage = $Current.StartPage
$EndPage = $LastPage

$Document = [iTextSharp.text.Document]::new($PdfReader.GetPageSizeWithRotation($StartPage))
$TargetMemoryStream = [System.IO.MemoryStream]::new()
$PdfCopy = [iTextSharp.text.pdf.PdfSmartCopy]::new($Document, $TargetMemoryStream)

$Document.Open()
foreach ($Page in $StartPage..$EndPage) {
$PdfCopy.AddPage($PdfCopy.GetImportedPage($PdfReader, $Page));
}
$Document.Close()

$NewFileName = 'Elementary Student Record - {0}.pdf' -f $Current.Student_Id
$NewFileFullName = [System.IO.Path]::Combine($OutputFolder, $NewFileName)
[System.IO.File]::WriteAllBytes($NewFileFullName, $TargetMemoryStream.ToArray())

$LastPage = $Current.StartPage - 1
}
}

在我的测试环境中,此过程在15秒钟内处理了5个源PDF的大约500名学生。

我倾向于使用构造函数而不是 New-Object,但是它们之间没有真正的区别。我只是觉得它们更容易阅读。

关于powershell - 在Powershell中使用itextsharp从PDF提取页面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52762604/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com