|
| 1 | +if ($this.'.Parts') { |
| 2 | + return $this.'.Parts' |
| 3 | +} |
| 4 | + |
| 5 | + |
| 6 | +filter getPartContent { |
| 7 | + $part = $_ |
| 8 | + $partStream = $part.GetStream() |
| 9 | + if (-not $partStream) { return } |
| 10 | + switch ($part.ContentType) { |
| 11 | + # If the content type looks like XML, read it as XML |
| 12 | + { $part.ContentType -match '[\./\+]xml' } { |
| 13 | + $streamReader = [IO.StreamReader]::new($partStream) |
| 14 | + $streamReader.ReadToEnd() -as [xml] |
| 15 | + $streamReader.Close() |
| 16 | + break |
| 17 | + } |
| 18 | + # If the part looks like JSON, read it as JSON |
| 19 | + { $part.Uri -match '\.json$'} { |
| 20 | + $streamReader = [IO.StreamReader]::new($partStream) |
| 21 | + $jsonContent = $streamReader.ReadToEnd() |
| 22 | + $streamReader.Close() |
| 23 | + $jsonContent | ConvertFrom-Json |
| 24 | + break |
| 25 | + } |
| 26 | + { $part.ContentType -match 'text/.+?$'} { |
| 27 | + $streamReader = [IO.StreamReader]::new($partStream) |
| 28 | + $textContent = $streamReader.ReadToEnd() |
| 29 | + $streamReader.Close() |
| 30 | + $textContent |
| 31 | + break |
| 32 | + } |
| 33 | + # Otherwise, read it as a memory stream and return the byte array |
| 34 | + default { |
| 35 | + $outputStream = [IO.MemoryStream]::new() |
| 36 | + $partStream.CopyTo($outputStream) |
| 37 | + $outputStream.Seek(0, 'Begin') |
| 38 | + $outputStream.ToArray() |
| 39 | + } |
| 40 | + } |
| 41 | + |
| 42 | + $partStream.Close() |
| 43 | + $partStream.Dispose() |
| 44 | +} |
| 45 | + |
| 46 | +$packageParts = @($this.GetParts()) |
| 47 | +$packageContent = [Ordered]@{} |
| 48 | + |
| 49 | +# Now we will read each part in the package, and store it in an `[Ordered]` dictionary |
| 50 | +# Since this _might_ take a while (if you used a lot of PowerPoint images) we want to show a progress bar. |
| 51 | + |
| 52 | +# Prepare the progress bar |
| 53 | +$partCount = 0 |
| 54 | +$partTotal = $packageParts.Length |
| 55 | +$partProgress = [Ordered]@{Id=Get-Random;Activity='Reading Parts'} |
| 56 | + |
| 57 | +# Then read each part |
| 58 | +@(foreach ($part in $packageParts) { |
| 59 | + $partCount++ |
| 60 | + # update the progress bar |
| 61 | + Write-Progress @partProgress -Status "Reading part $($part.Uri) ($partCount of $partTotal)" -PercentComplete ( |
| 62 | + [math]::Round(($partCount * 100/ $partTotal)) |
| 63 | + ) |
| 64 | + # and store the part in the dictionary |
| 65 | + $packageContent["$($part.Uri)"] = |
| 66 | + [PSCustomObject]@{ |
| 67 | + PSTypeName = 'OpenXML.Part' |
| 68 | + Uri = $part.Uri |
| 69 | + ContentType = $part.ContentType |
| 70 | + # (we'll use our helper function to get the content) |
| 71 | + Content = $part | getPartContent |
| 72 | + FilePath = "$resolvedPath" |
| 73 | + } |
| 74 | +}) |
| 75 | +<## Now that we've read all parts, we can close the package |
| 76 | +$filePackage.Close() |
| 77 | +# and the memory stream, too. |
| 78 | +$memoryStream.Close()#> |
| 79 | + |
| 80 | +# and finally, complete the progress bar. |
| 81 | +Write-Progress @partProgress -Status "Completed reading $partCount parts" -Completed |
| 82 | +$this | Add-Member NoteProperty '.Parts' -Force $packageContent |
| 83 | + |
| 84 | +return $this.'.Parts' |
0 commit comments