Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Extract exams from a PDF file. See https://idrissi.eu/en/post/select-exams/ for more information.
<#
.SYNOPSIS
Splits a PDF file containing multiple exams along ranges specified in a CSV file, to be used with Moodle.
.PARAMETER InputCSV
The path of the CSV file that explains how to split the PDF file. The headers of that CSV file should be:
- Name: The name of the student.
- ID: The Moodle participant for the student in that specific course (distinct from the global Moodle ID).
- Start: The first page of that student's exam.
- End: The last page of that student's exam.
.PARAMETER InputPDF
The path of the PDF containing all the pages of the students' exams.
.PARAMETER OutputZip
The path of the zip file to be created.
.PARAMETER Delimiter
The delimiter used in the CSV file.
#>
[CmdletBinding()]
param (
[Parameter(Mandatory)] [String] $InputCSV,
[Parameter(Mandatory)] [String] $InputPDF,
[Parameter(Mandatory)] [String] $OutputZip,
[String] $Delimiter = ","
)
if (!(Get-Command "pdftk.exe" -ErrorAction SilentlyContinue)) {
Write-Error "PDFtk must be installed for this script to work."
exit 1
}
foreach ($file in @($InputCSV, $InputPDF)) {
if (!(Test-Path $file)) {
Write-Error "Cannot find file $file."
exit 1
}
}
$ImportedCSV = Import-Csv -Path $InputCSV -Delimiter $Delimiter
Write-Verbose "Imported $InputCSV."
$PDFItem = Get-Item $InputPDF
$TempFolder = Join-Path $Env:Temp $(New-Guid)
Write-Verbose "Creating and moving to $TempFolder..."
New-Item -Type Directory -Path $TempFolder | Out-Null
Push-Location $TempFolder
Write-Verbose "Bursting the PDF..."
# this produces files named pg_0001.pdf, pg_0002.pdf etc
pdftk.exe $PDFItem burst
$FinalFolder = New-Item -Name "final" -Type Directory
foreach ($entry in $ImportedCSV) {
Write-Verbose "Entry: $entry"
if ((!$entry.Start) -or (!$entry.End)) {
Write-Warning ("Skipping {0}!" -f $entry.Name)
}
else {
$OutputPDF = Join-Path "final" ("{0}_{1}_assignsubmission_file_Copie {0}.pdf" -f $entry.Name, $entry.ID)
$Range = ($entry.Start)..($entry.End) | ForEach-Object { "pg_{0:d4}.pdf" -f $_ }
Write-Verbose "Running pdftk with Range = $Range and OutputPDF = $OutputPDF..."
pdftk.exe @Range output $OutputPDF
}
}
Write-Verbose "Finished exporting PDFs."
Pop-Location
Write-Verbose "Compressing to $OutputZip..."
Compress-Archive -Path (Get-ChildItem $FinalFolder) -DestinationPath $OutputZip
Write-Verbose "Removing $TempFolder..."
Remove-Item -Recurse $TempFolder
Name ID Start End
Doe 12345 1 4
Jekyll 42 5 8
Hyde 666 9 12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment