PowerShell · 21.08.2022

JPG: Немедленно в A4 PDF

Про создание документа MS Word из среды PowerShell почерпнул здесь.

Столкнулся с задачей: нужно распечатать кучу картинок в формате JPG. Тривиально, — скажете Вы. Да, но задача усложнилась — нужен ещё .pdf формата А4 и чтобы все картинки в нём были только в книжной ориентации. Исполнение — максимально быстро, а в идеале — в один клик. Само собой, устанавливать стороннее ПО нельзя. Из того, что есть под рукой — только MS Word… И PowerShell.

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

## Заголовок скрипта ##
[System.Console]::Title = "Из JPG в PDF (Формат листа А4)"

## Подключение ссылки на System.Drawing к текущей сессии PS ##
[System.Reflection.Assembly]::LoadWithPartialName("System.Drawing") | Out-Null

## Блок вызова MS Word ##
$word = New-Object -ComObject Word.Application
$word.Visible = $False
$doc = $word.Documents.Add()
$selection = $word.Selection
$selection.Pagesetup.TopMargin = 50
$selection.Pagesetup.LeftMargin = 50
$selection.Pagesetup.RightMargin = 50
$selection.Pagesetup.BottomMargin = 50
$selection.ParagraphFormat.SpaceBefore = 0
$selection.ParagraphFormat.SpaceAfter = 0
$selection.ParagraphFormat.Alignment = 1

## Смена расширения с jpeg на jpg ##
Get-Childitem | Where-Object { $_.extension -eq ".jpeg" } | Rename-Item -NewName { [IO.Path]::ChangeExtension($_.Name, ".jpg") }

## Обработка изображений и добавление в документ ##
Write-Host "Начата конвертация..." -ForegroundColor Cyan
Write-Host
$path = Get-Childitem | Where-Object { $_.extension -eq ".jpg"}
ForEach ($i in $path) {
    $image = [System.Drawing.image]::FromFile($i)
    if ($image.height -lt $image.width) {
        $image.rotateflip("Rotate90FlipNone")
        $image.save($i) }
    $jpg = $i.FullName
    $forprint = $selection.InlineShapes.AddPicture($jpg) | Out-Null
}

## Сохранение файла PDF и вывод документа ##
Write-Host "Идёт сохранение в PDF..." -ForegroundColor Cyan
Write-Host
$savetopdf = $PSScriptRoot + "\outfile.pdf"
$doc.saveas([ref] $savetopdf, [ref] 17)

## Прямая отправка на печать из Word ##
# $doc.PrintOut([ref] $false) # Раскоментируйте строку если требуется прямая печать

## Выход из MS Word без сохранения ##
$word.Documents.Close($false)
$word.Quit()

Логика скрипта такая: загружается System.Drawing для обработки изображений, создаётся документ Word, цикл проходит по всем файлам формата .jpg (присутствует обработчик для .jpeg файлов), на лету получает ширину и высоту файла, меняет ориентацию с альбомной на книжную (если это нужно), а в завершении запихивает картинки в документ, сохраняет файл в один большой pdf.

По итогам — скрипт закрывает документ Word без сохранения. Всё!

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