2016-03-14 85 views
4

我有一個Powershell腳本,它使用iTextSharp從PDF文件中提取文本。腳本下載的文件之一是橫向的,所以需要旋轉以便腳本讀取它。使用Powershell和iTextSharp旋轉PDF

這裏是我的功能讀取 PDF。我已經測試過它,它的工作原理如下:

function Get-PdfText { 
    [CmdletBinding()] 
    [OutputType([string])] 
    param (
     [Parameter(Mandatory = $true)] 
     [string] 
     $Path 
    ) 

    try { 
     $reader = New-Object iTextSharp.text.pdf.pdfreader -ArgumentList $Path 
    } 
    catch { 
     throw 
    } 

    $stringBuilder = New-Object System.Text.StringBuilder 

    for ($page = 1; $page -le $reader.NumberOfPages; $page++) { 
     $text = [iTextSharp.text.pdf.parser.PdfTextExtractor]::GetTextFromPage($reader, $page) 
     $null = $stringBuilder.AppendLine($text) 
    } 

    $reader.Close() 

    return $stringBuilder.ToString() 
} 

關於如何在C#和Java中,而不是在Powershell中旋轉PDF文檔有很多文檔。有一個很好的例子在這裏,但我不知道如何將其轉換爲PowerShell的: http://developers.itextpdf.com/question/how-rotate-page-90-degrees

這是我在將其轉換嘗試:

function RotatePdf90Degrees { 
    param (
     [Parameter(Mandatory = $true)] 
     [string] 
     $Path 
    ) 

    $reader = New-Object iTextSharp.text.pdf.PdfReader -ArgumentList $Path 
    $n = $reader.NumberOfPages 
    $page #PdfDictionary 
    $rotate #PdfNumber 
    for ($p = 1; $p -le $n; $p++) { 
     $page = $reader.GetPageN($p); 
     $rotate = $page.GetAsNumber([iTextSharp.text.pdf.PdfName]::ROTATE); 
     if ($rotate -eq $null) { 
      $page.put([iTextSharp.text.pdf.PdfName]::ROTATE, [iTextSharp.text.pdf]::PdfNumber(90)); 
     } 
     else { 
      $page.put([iTextSharp.text.pdf.PdfName]::ROTATE, [iTextSharp.text.pdf]::PdfNumber(($rotate.IntValue() + 90) % 360)); 
     } 
    } 

    $stamper = New-Object iTextSharp.text.pdf.PdfStamper ($reader, [System.IO.StreamWriter] $Path); 
    $stamper.Close(); 
    $reader.Close(); 
} 

有些事情不對的$ page.put()線。我不知道如何爲該函數提供適當的PdfNumber對象。

我一直在使用這個文件: http://developers.itextpdf.com/reference/package/com.itextpdf.text.pdf

+0

嘗試在'New-Object [iTextSharp.text中拋出'New-Object'。pdf] :: PdfNumber(90)' –

+0

該腳本將不會編譯。 「表達式或語句中的意外標記'New-Object'」。 – Fungusface

+0

對不起,PowerShell非常類似c#,但不完全。 'PdfNumber'是一個對象,所以你需要以某種方式「新」,但我不知道你是否可以內聯。 'New-Object iTextSharp.text.pdf.PdfNumber(90)'怎麼樣?如果這不起作用,請嘗試將其設置爲一個變量,然後將該變量傳遞給'put'方法。 –

回答

2

也許我們正在努力過不同版本的powershell,但我與你的樣本函數具有第一個問題就在這裏,

[iTextSharp.text.pdf.PdfName]::ROTATE; 

其中引發以下例外:

的字段或屬性: 「CA」 用於類型: 「iTextSharp.text.pdf.PdfName」 僅在字段或屬性的字母套中有所不同:「CA」。 類型必須符合公共語言規範(CLS)。

望着iTextSharp源代碼,有作爲例外,指出兩個獨立的領域:

  • PdfName.CA
  • PdfName.ca

沒有寫任何PowerShell的在一段時間,所以最簡單的解決方法是用相同的實例化一個新的PdfName對象字符串用於源碼中的PdfName.ROTATE。無論如何,希望下面讓你開始:

function Rotate-Pdf { 
    [CmdletBinding()] 
    param(
     [parameter(Mandatory=$true)] [string]$readerPath 
     ,[parameter(Mandatory=$true)] [float]$degrees 
    ) 
    $reader = New-Object iTextSharp.text.pdf.PdfReader($readerPath); 
    $rotate = New-Object iTextSharp.text.pdf.PdfName('Rotate'); 
    $pdfNumber = New-Object iTextSharp.text.pdf.PdfNumber($degrees); 
    $pageCount = $reader.NumberOfPages; 
    for ($i = 1; $i -le $pageCount; $i++) { 
     # $rotation = $reader.GetPageRotation($i); 
     $pageDict = $reader.GetPageN($i); 
     $pageDict.Put($rotate, $pdfNumber); 
    } 
    $memoryStream = New-Object System.IO.MemoryStream; 
    $stamper = New-Object iTextSharp.text.pdf.PdfStamper($reader, $memoryStream); 
    $stamper.Dispose(); 
    $bytes = $memoryStream.ToArray(); 
    $memoryStream.Dispose(); 
    $reader.Dispose(); 
    return $bytes; 
} 
$bytes = Rotate-Pdf $input 90; 
[System.IO.File]::WriteAllBytes($output, $bytes); 

注意,有一個爲度旋轉一個額外的參數,並註釋掉$reader.GetPageRotation()。取決於如何創建PDF,you cannot always count on PdfReader.GetPageRotation()

UPDATE

確認異常上面提到的是特定於PowerShell的4.0。沒有測試V3.0,但在使用V2.0時,[iTextSharp.text.pdf.PdfName]::ROTATE不是拋出ExtendedTypeSystemException,並且運行沒有問題。

+0

謝謝,當我有機會時,我會試試這個。 – Fungusface

+0

似乎它的工作。謝謝! – Fungusface