2016-03-14 43 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