Главная > Powershell > Конвертирование .doc файлов в .pdf с помощью Powershell

Конвертирование .doc файлов в .pdf с помощью Powershell

Сравнительно недавно на глаза попалась заметка о том как конвертировать .doc файлы в .pdf при помощи Powershell. Тогда я на неё посмотрел подумав, что это хорошо, нужно сохранить, может пригодится в будущем.

Будущее настало довольно быстро – на днях прибежали взволнованные пользователи столкнувшись с проблемой конвертирования большого количества  вёрдовских файлов в pdf (и вроде как теперь это нужно будет делать регулярно с какой-то там периодичностью). При чём пугал их не сам многократно повторяющийся процесс  (они уже и файлы поделили по честному по ровну), а невозможность сохранить текст из вёрда в pdf (Office 2007).

Для того, чтобы можно было сохранять вёрдовские документы в pdf нужно установить специальную надстройку. Устанавливая эту надстройку вспомнил о той самой заметке, и решил помочь своим любимым пользователям, взяв за основу показанный пример и немного его переделав.

По умолчанию скрипт будет искать файлы в текущем каталоге, но при желании/необходимости можно задать путь, указав его в качестве параметра:

param
(
    [string]$path = $null
)

# Если путь не задан ищем в текущем каталоге
if (!$path)
{
    $path = Get-Location
    Write-Warning "Путь не задан, по умолчанию используется текущий путь: $path"
}

После того как определились с каталогом отбираем в нём doc-файлы, и если не находим завершаем работу – нам здесь делать больше нечего:

# Ищем .doc файлы
$docs = Get-ChildItem $path -Filter "*.doc"
if (!$docs)
{
    Write-Error -Category ObjectNotFound `
        -Message "В указанном каталоге .doc файлы не найдены" `
        -TargetObject $path
    exit
}

Посовещавшись с пользователями решили, что сохранять pdf файлы так, чтобы их было легко найти проще всего в специально созданный для них каталог в том же каталоге, в котором лежат исходные доки. Поэтому создаём каталог PDF по указанному ранее пути, предварительно проверив его существование (ну если мы здесь уже были, то не создаём):

$pdf_path = $path + "\PDF"
if (!(Test-Path $pdf_path))
{
    Write-Verbose "Создаём каталог $pdf_path`n" -Verbose
    New-Item -ItemType directory -Path $pdf_path | Out-Null
}

(Также была мысль при существовании каталога как-то контролировать наличие одноимённых pdf-файлов, и как-то на это реагировать, но пользователи одноголосно утверждали, что если существующий файл будет затёрт то так даже лучше, поэтому без этого обошлись.)

Далее начинаем по одному конвертировать файлы, попутно выводя на экран имя и номер конвертируемого в данный момент файла (чтобы видно было, что скрипт работает, а не заснул):

# Количество .doc файлов
$count = $docs.Count

# Создаём объект Word
$word = New-Object -ComObject Word.Application
$word.Visible = $false

foreach ($file in $docs)
{
    # Номер и имя обрабатываемого файла
    $name = $file.Name
    ++$number
    Write-Verbose "$name `t`t (файл $number из $count)" -Verbose

    # Открываем файл
    $doc = $word.Documents.Open($file.FullName)
    
    # Задаём имя и путь к pdf файлу
    $pdf_file = $pdf_path + "\" + $doc.Name
    
    # Меняем расширение (иначе будет pdf-файл с расширением doc)
    $pdf_file = [System.IO.Path]::ChangeExtension($pdf_file, '.pdf')
    
    # Конвертируем
    $doc.ExportAsFixedFormat($pdf_file, 'wdExportFormatPDF', $false, 1)
    
    # Закрываем Файл
    $doc.Close()
}

# Закрываем Word
$word.Quit()

Конвертирование осуществляется вызовом метода ExportAsFixedFormat, который сохраняет документ в формате PDF или XPS. Формат файла определяется свойством WdExportFormat, которое может принимать значения wdExportFormatPDF для сохранения в pdf, или wdExportFormatXPS соответственно для XPS (в этом случае также нужно изменить расширение на .xps). После того как все файлы экспортированы закрываем Word, заканчиваем работу и принимаем благодарности пользователей тихонько радуясь про себя тому, что сделали мир чуточку лучше :).

Рубрики:Powershell Метки: , ,
  1. 21/12/2016 в 16:23

    Друзья привет! Спасибо за статью, потребовалось перегонять большой массив документов около 6к, во множестве вложенных папок, пришло переделать исходный скрипт под себя.

    $path = «D:\testpdf»

    $dirsname = (Get-ChildItem $path -Directory -recurse).FullName
    $pdf_path = $dirsname
    $docscount = Get-ChildItem $path -Filter «*.doc» -recurse

    $word = New-Object -ComObject Word.Application
    $word.Visible = $false

    $Core = foreach ($PDF1 in $pdf_path)
    {
    $docs = Get-ChildItem $PDF1 -Filter «*.doc»
    foreach ($File in $docs){
    $fullname = $PDF1 + «\PDF»
    if (!(Test-Path $fullname))
    {
    Write-Verbose «Создаём каталог $fullname`n» -Verbose
    New-Item -ItemType directory -Path $fullname | Out-Null
    }

    #Convert
    $count = $docscount.Count
    $name = $file.Name
    ++$number
    Write-Verbose «$name `t`t (файл $number из $count)» -Verbose
    $doc = $word.Documents.Open($file.FullName)
    $pdf_file = $fullname + «\» + $doc.Name
    $pdf_file = [System.IO.Path]::ChangeExtension($pdf_file, ‘.pdf’)
    $doc.ExportAsFixedFormat($pdf_file,17, $false, 1)
    $doc.Close()
    }
    }
    $word.Quit()

    • 21/12/2016 в 16:27

      Забыл добавить, что в каждом новом каталоге создается отдельная папка, где уже располагаются необходимые документы.

      • 23/12/2016 в 07:03

        В процессе выявилась проблема, если документ имеет какие-то проблемы, то word автоматически хочет их исправить, как и в примере так и в моем варианте, при возникновении данной ошибки, выполнение скрипта останавливается. Информации ни какой не выводится, в данный момент решил проблему так:

        Запихнул в цикл foreach

        $word = New-Object -ComObject Word.Application
        $word.Visible = $false

        $word.Quit() — соответственно в конце цикла

        После этого при возникновении ошибка, открывается word, который предлагает уже принять решение, этот момент просто скипается(руками) и скрипт продолжает работать. Стоит заметить, что данный вариант, увеличивает время на обработку документа и повышает нагрузку на процессор.

        Еще раз спасибо, за исходники!!!!!!!!!!!

    • 22/12/2016 в 12:38

      И Вам спасибо за такой подробный комментарий 🙂

  2. Green_ya
    20/01/2020 в 17:40

    Как же вовремя я нашел ваши скрипты! Спасибо вам огромное! А то я уже свой почти написал =) Хотя пожалуй свой допишу. Но вам все равно огромное спасибо!

  1. 15/02/2019 в 15:17
  2. 06/12/2023 в 17:47

Оставьте комментарий