web-dev-qa-db-fra.com

Powershell de base - convertir par lots Word Docx en PDF

J'essaie d'utiliser PowerShell pour effectuer une conversion par lots de Word Docx en PDF - en utilisant un script trouvé sur ce site: http://blogs.technet.com/b/ heyscriptingguy/archive/2013/03/24/weekend-scripteur-convert-documents-Word-en-fichiers-pdf-avec-powershell.aspx

# 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()
}

Et je continue à recevoir cette erreur et je n'arrive pas à comprendre pourquoi:

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

Des idées?

Aussi - comment aurais-je besoin de le changer pour convertir également des fichiers doc (pas docX), ainsi que pour utiliser les fichiers locaux (fichiers au même emplacement que l'emplacement du script)?

Désolé - jamais fait de script PowerShell ...

24
takabanana

Cela fonctionnera pour les fichiers doc et docx.

$documents_path = 'c:\doc2pdf'

$Word_app = New-Object -ComObject Word.Application

# This filter will find .doc as well as .docx documents
Get-ChildItem -Path $documents_path -Filter *.doc? | ForEach-Object {

    $document = $Word_app.Documents.Open($_.FullName)

    $pdf_filename = "$($_.DirectoryName)\$($_.BaseName).pdf"

    $document.SaveAs([ref] $pdf_filename, [ref] 17)

    $document.Close()
}

$Word_app.Quit()
50
MFT

Les réponses ci-dessus ont toutes échoué pour moi, car je faisais un travail par lots convertissant environ 70 000 documents Word de cette façon. En fin de compte, faire cela à plusieurs reprises conduit finalement à un plantage de Word, probablement en raison de problèmes de mémoire (l'erreur était une exception COMException que je ne savais pas comment analyser). Donc, mon hack pour le faire continuer était de tuer et de redémarrer Word toutes les 100 documents (nombre choisi arbitrairement).

De plus, en cas de plantage occasionnel, il en résulterait des fichiers PDF malformés, dont chacun avait généralement une taille de 1 à 2 Ko. Ainsi, lorsque je saute des fichiers PDF déjà générés, je m'assure qu'ils ont une taille d'au moins 3 Ko. Si vous ne souhaitez pas ignorer les PDF déjà générés, vous pouvez supprimer cette instruction if.

Excusez-moi si mon code ne semble pas bon, je n'utilise généralement pas Windows et c'était un hack ponctuel. Voici donc le code résultant:

$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
}
3
osdiab

Cela fonctionne pour moi (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()
3
David Brabant

Aucune des solutions publiées ici n'a fonctionné pour moi sur Windows 8.1 (en passant. J'utilise Office 365). Mon PowerShell n'aime pas les arguments [ref] (je ne sais pas pourquoi, j'utilise PowerShell très rarement).

C'est la solution qui a fonctionné pour moi:

$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()
}
1
Honza Kalfus