Powershell de base - conversion par lots Word Docx en PDF

J'essaie D'utiliser PowerShell pour faire 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-scripter-convert-word-documents-to-pdf-files-with-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 j'obtiens toujours cette erreur et ne peut pas comprendre pourquoi:

PS C:docx2pdf> .docx2pdf.ps1
Exception calling "SaveAs" with "16" argument(s): "Command failed"
At C:docx2pdfdocx2pdf.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 aussi convertir doc (pas docX) des fichiers, ainsi comme utiliser les fichiers locaux (fichiers au même endroit que l'emplacement du script)?

Désolé - je n'ai jamais fait de scripts PowerShell...

19
demandé sur takabanana 2013-05-14 06:44:23

4 réponses

cela fonctionnera pour les fichiers doc aussi bien que 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()
44
répondu MFT 2013-05-14 08:04:53

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
répondu David Brabant 2013-05-14 07:11:32

aucune des solutions affichées ici n'a fonctionné pour moi sur Windows 8.1 (btw. Je suis à l'aide d'Office 365). Ma 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
répondu Honza Kalfus 2015-05-24 09:00:48

les réponses ci-dessus me manquaient, car je faisais un travail par lots en convertissant environ 70.000 documents word de cette façon. Comme il s'avère, faire cela à plusieurs reprises conduit éventuellement à des mots s'écraser, probablement en raison de problèmes de mémoire (l'erreur était une certaine COMException que je ne savais pas comment analyser). Donc, mon hack pour le faire procéder était de tuer et redémarrer word tous les 100 docs (nombre choisi arbitrairement).

en Outre, quand il plante parfois, il n'y aurait résultant les PDF mal formés, dont chacun était généralement de 1 à 2 kb. Ainsi, en sautant déjà produit des PDF, je m'assure qu'ils sont au moins 3kb dans la taille. Si vous ne voulez pas sauter les PDF déjà générés, vous pouvez supprimer cette instruction if.

Excusez-moi si mon code n'a pas l'air bon, je n'utilisez Windows et que c'était un hack. Donc, voici le 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
}
0
répondu Omar Diab 2016-12-20 09:51:06