2013-05-14 11 views
19

Ich versuche, Powershell zu verwenden, um eine Batch-Konvertierung von Word DOCX zu PDF zu tun - einem Skript auf dieser Seite gefunden werden: http://blogs.technet.com/b/heyscriptingguy/archive/2013/03/24/weekend-scripter-convert-word-documents-to-pdf-files-with-powershell.aspxGrundpowershell - Batch-Konvertierung von Word-Docx zu PDF

# Acquire a list of DOCX files in a folder 
$Files=GET-CHILDITEM "C:\docx2pdf\*.DOCX" 
$Word=NEW-OBJECT –COMOBJECT WORD.APPLICATION 

Foreach ($File in $Files) { 
    # open a Word document, filename from the directory 
    $Doc=$Word.Documents.Open($File.fullname) 

    # Swap out DOCX with PDF in the Filename 
    $Name=($Doc.Fullname).replace("docx","pdf") 

    # Save this File as a PDF in Word 2010/2013 
    $Doc.saveas([ref] $Name, [ref] 17) 
    $Doc.close() 
} 

Und ich halte auf bekommen diesen Fehler und kann nicht herausfinden warum:

PS C:\docx2pdf> .\docx2pdf.ps1 
Exception calling "SaveAs" with "16" argument(s): "Command failed" 
At C:\docx2pdf\docx2pdf.ps1:13 char:13 
+  $Doc.saveas <<<< ([ref] $Name, [ref] 17) 
    + CategoryInfo   : NotSpecified: (:) [], MethodInvocationException 
    + FullyQualifiedErrorId : DotNetMethodException 

Irgendwelche Ideen?

Auch - wie müsste ich es ändern, um auch doc (nicht docX) -Dateien zu konvertieren, sowie die lokalen Dateien (Dateien am selben Ort wie der Ort des Skripts) zu verwenden?

Sorry - nie Scripting Powershell getan ...

Antwort

42

Dies wird für doc arbeiten sowie docx-Dateien.

+4

Das funktionierte - dank - geändert $ documents_path dynamisch zu sein, basierend auf Skript Standort mithilfe von '$ documents_path = Split-Path -parent $ MyInvocation.MyCommand.Path' – takabanana

+0

Ist oledb verwendet in dieser Umwandlung? – culter

+2

Sie sollten auch das COM-Objekt freigeben: '[System.Runtime.Interopservices.Marshal] :: ReleaseComObject ($ word_app)'. Das Entfernen der gesamten Variablen wird auch von [The Scripting Guys] vorgeschlagen (http://technet.microsoft.com/en-us/library/ff730962.aspx): 'Remove-Variable word_app' – ComFreek

3

Dies funktioniert für mich (Word 2007):

$wdFormatPDF = 17 
$word = New-Object -ComObject Word.Application 
$word.visible = $false 

$folderpath = Split-Path -parent $MyInvocation.MyCommand.Path 

Get-ChildItem -path $folderpath -recurse -include "*.doc" | % { 
    $path = ($_.fullname).substring(0,($_.FullName).lastindexOf(".")) 
    $doc = $word.documents.open($_.fullname) 
    $doc.saveas($path, $wdFormatPDF) 
    $doc.close() 
} 

$word.Quit() 
1

Keine der hier veröffentlichten Lösungen funktionierte für mich unter Windows 8.1 (übrigens. Ich verwende Office 365). Meine PowerShell mag die [ref] Argumente irgendwie nicht (ich weiß nicht warum, ich benutze PowerShell sehr selten).

Dies ist die Lösung, die für mich gearbeitet:

$Files=Get-ChildItem 'C:\path\to\files\*.docx' 

$Word = New-Object -ComObject Word.Application 

Foreach ($File in $Files) { 
    $Doc = $Word.Documents.Open($File.FullName) 
    $Name=($Doc.FullName).replace('docx', 'pdf') 
    $Doc.SaveAs($Name, 17) 
    $Doc.Close() 
} 
0

Die oben genannten Antworten alle für mich fiel kurz, wie ich auf diese Weise rund 70.000 Word-Dokumente konvertieren eine Batch-Job tat. Wie sich herausstellt, führt dies wiederholt dazu, dass Word abstürzt, vermutlich aufgrund von Speicherproblemen (der Fehler war eine COMException, die ich nicht parsen konnte). Also, mein Hack, um es fortzufahren, war, alle 100 Dokumente (beliebig gewählte Zahl) zu töten und neu zu starten.

Darüber hinaus, wenn es gelegentlich abstürzte, würde es zu fehlerhaften PDFs, die jeweils im Allgemeinen 1-2 KB groß waren. Wenn ich also bereits erstellte PDFs überspringe, stelle ich sicher, dass sie mindestens 3kb groß sind. Wenn Sie bereits generierte PDFs nicht überspringen möchten, können Sie diese if-Anweisung löschen.

Entschuldigung, wenn mein Code nicht gut aussieht, verwende ich normalerweise nicht Windows und das war ein einmaliger Hack. So, hier ist der resultierende Code:

$Files=Get-ChildItem -path '.\path\to\docs' -recurse -include "*.doc*" 

$counter = 0 
$filesProcessed = 0 
$Word = New-Object -ComObject Word.Application 

Foreach ($File in $Files) { 
    $Name="$(($File.FullName).substring(0, $File.FullName.lastIndexOf("."))).pdf" 
    if ((Test-Path $Name) -And (Get-Item $Name).length -gt 3kb) { 
     echo "skipping $($Name), already exists" 
     continue 
    } 

    echo "$($filesProcessed): processing $($File.FullName)" 
    $Doc = $Word.Documents.Open($File.FullName) 
    $Doc.SaveAs($Name, 17) 
    $Doc.Close() 
    if ($counter -gt 100) { 
     $counter = 0 
     $Word.Quit() 
     [System.Runtime.Interopservices.Marshal]::ReleaseComObject($Word) 
     $Word = New-Object -ComObject Word.Application 
    } 
    $counter = $counter + 1 
    $filesProcessed = $filesProcessed + 1 
}