PowerPointからPDFの出力を自動化する

仕事でPowerPointを複数(10数ファイル)作ったのですが、これが配布用にPDFを出力するのがすごく面倒。

一つ一つパワポのファイルを開いて、2スライド/ページの形式を選択して保存(単純にPDFだけ指定すると1スライド/ページになります。毎回発行オプションで「配布資料」の指定するのがとにかくめんどう)。単純な作業ですが、かなりストレスになります。

それにパワポ作っていると、頻繁に修正も発生します。そのたびに作り直すのも時間が掛かります。

PowerShellで自動化する

そんなわけで、powershellスクリプトを使って自動化してみました。やりたかったのは以下の2つ。

  • 指定したフォルダのすべてのpptx形式を対象にする
  • 2スライド/ページ形式でPDFへエクスポートする

単純にスクリプトが配置されたフォルダに以下2つのフォルダがあるのを前提にして処理します。

フォルダ内容
.\pptxPDFへエクスポートした.pptx形式のファイル
.\releasePDFの保存先

以下、ちょっと長いですがスクリプト全文です。

# リンク先を参考にした。
# https://gist.github.com/ap0llo/05cef76e3c4040ee924c4cfeef3f0b40
function Export-Presentation($inputFile)
{
	# Load Powerpoint Interop Assembly
	#[Reflection.Assembly]::LoadWithPartialname("Microsoft.Office.Interop.Powerpoint") > $null
	#[Reflection.Assembly]::LoadWithPartialname("Office") > $null

	# $msoFalse =  [Microsoft.Office.Core.MsoTristate]::msoFalse
	# $msoTrue =  [Microsoft.Office.Core.MsoTristate]::msoTrue
	Set-Variable msoFalse 0 -Option Constant -ErrorAction SilentlyContinue
	Set-Variable msoTrue -1 -Option Constant -ErrorAction SilentlyContinue

	#$ppFixedFormatIntentScreen = [Microsoft.Office.Interop.PowerPoint.PpFixedFormatIntent]::ppFixedFormatIntentScreen # Intent is to view exported file on screen.
	#$ppFixedFormatIntentPrint =  [Microsoft.Office.Interop.PowerPoint.PpFixedFormatIntent]::ppFixedFormatIntentPrint  # Intent is to print exported file.

	#$ppFixedFormatTypeXPS = [Microsoft.Office.Interop.PowerPoint.PpFixedFormatType]::ppFixedFormatTypeXPS  # XPS format
	#$ppFixedFormatTypePDF = [Microsoft.Office.Interop.PowerPoint.PpFixedFormatType]::ppFixedFormatTypePDF  # PDF format

	$ppPrintHandoutVerticalFirst = 1   # Slides are ordered vertically, with the first slide in the upper-left corner and the second slide below it.
	$ppPrintHandoutHorizontalFirst = 2 # Slides are ordered horizontally, with the first slide in the upper-left corner and the second slide to the right of it.

	# pdfの出力形式
	$ppPrintOutputSlides = 1               # Slides
	$ppPrintOutputTwoSlideHandouts = 2     # Two Slide Handouts
	$ppPrintOutputThreeSlideHandouts = 3   # Three Slide Handouts
	$ppPrintOutputSixSlideHandouts = 4     # Six Slide Handouts
	$ppPrintOutputNotesPages = 5           # Notes Pages
	$ppPrintOutputOutline = 6              # Outline
	$ppPrintOutputBuildSlides = 7          # Build Slides
	$ppPrintOutputFourSlideHandouts = 8    # Four Slide Handouts
	$ppPrintOutputNineSlideHandouts = 9    # Nine Slide Handouts
	$ppPrintOutputOneSlideHandouts = 10    # Single Slide Handouts

	$ppPrintAll = 1            # Print all slides in the presentation.
	$ppPrintSelection = 2      # Print a selection of slides.
	$ppPrintCurrent = 3        # Print the current slide from the presentation.
	$ppPrintSlideRange = 4     # Print a range of slides.
	$ppPrintNamedSlideShow = 5 # Print a named slideshow.

	$ppShowAll = 1             # Show all.
	$ppShowNamedSlideShow = 3  # Show named slideshow.
	$ppShowSlideRange = 2      # Show slide range.

	
	# start Powerpoint
	# $application = New-Object "Microsoft.Office.Interop.Powerpoint.ApplicationClass" 
	$application = New-Object -COMOBJECT Powerpoint.Application 
	#$word = NEW-OBJECT -COMOBJECT WORD.APPLICATION

	# Write-Host "Hello $inputFile"

	# Make sure inputFile is an absolte path
	$inputFile = Resolve-Path $inputFile
	
	# Write-Host "Hello $inputFile"
	
	$outputFile = [System.IO.Path]::ChangeExtension($inputFile, ".pdf")
	
	# $application.Visible = $msoTrue
	# $presentation = $application.Presentations.Open($inputFile, $msoTrue, $msoFalse, $msoFalse)
	# $presentation = $application.Presentations.Open($inputFile, $msoFalse, $msoFalse, $msoFalse)
	$presentation = $application.Presentations.Open($inputFile)
	# pause
	$printOptions = $presentation.PrintOptions
	
		# Write-Host "Count: $presentation.Slides.Count"
	# pause
	# $range = $printOptions.Ranges.Add(1,$presentation.Slides.Count) 
	$range = $printOptions.Ranges.Add(1,2) #後続の引数ですべて印刷をしていするため、ここはダミーで(1,2)
	$printOptions.RangeType = $ppShowAll
	
	# export presentation to pdf 
	$FrameSlides= -1 #フレームあり
	# $FrameSlides= 0	#フレームなし
	

	# 2スライド/ページでPDFを保存する
	$presentation.ExportAsFixedFormat($outputFile, $ppFixedFormatTypePDF, $ppFixedFormatIntentPrint, $FrameSlides, $ppPrintHandoutHorizontalFirst, $ppPrintOutputTwoSlideHandouts, $msoFalse, $range, $ppPrintAll, "Slideshow Name", $False, $False, $False, $False, $False)
	# 3スライド/ページでPDFを保存する
	# $presentation.ExportAsFixedFormat($outputFile, $ppFixedFormatTypePDF, $ppFixedFormatIntentPrint,$FrameSlides, $ppPrintHandoutHorizontalFirst, $ppPrintOutputThreeSlideHandouts, $msoFalse, $range, $ppPrintAll, "Slideshow Name", $False, $False, $False, $False, $False)
	
	$presentation.Close()
	$presentation = $null
	
	if($application.Windows.Count -eq 0)
	{
		$application.Quit()
	}
	
	$application = $null
	
	# Make sure references to COM objects are released, otherwise powerpoint might not close
	# (calling the methods twice is intentional, see https://msdn.microsoft.com/en-us/library/aa679807(office.11).aspx#officeinteroperabilitych2_part2_gc)
	[System.GC]::Collect();
	[System.GC]::WaitForPendingFinalizers();
	[System.GC]::Collect();
	[System.GC]::WaitForPendingFinalizers();

	return $outputFile
}

#-----------------------------------------------------------------------------
# PowerPointをPDFへエクスポート、リリースフォルダへ移動する
#-----------------------------------------------------------------------------
# pptxが保存されているフォルダ、pdfの保存先を設定する
# この例ではpowershellスクリプトのフォルダ直下にpptx、releaseフォルダがあるのを前提にしている。
# ・"pptx"	pptxが保存されたフォルダ
# ・"release" pdfの保存先フォルダ
$current_path = Split-Path $MyInvocation.MyCommand.Path
$pptx_folder = $current_path+"\pptx"
$release_folder = $current_path+"\release"

# $relese_filderが存在しなければ作成する
If(!(test-path $release_folder))
{
	New-Item -ItemType Directory -Force -Path $release_folder
}

$sources = $pptx_folder +"\*.pptx"
$files = Get-Item $sources

# pptxからPDF形式でエクスポート、releaseフォルダへ移動する
foreach($file in $files){
	write-host('+', $file)
	# 配布用PDFを作成する
	$pdf_file = Export-Presentation $file
	# PDFをリリース用フォルダへ上書きで移動する
	Move-Item $pdf_file $release_folder -force
}

実行方法

コマンドラインからスクリプト(この例ではbuild.ps1)を指定して実行。

powershell -ExecutionPolicy RemoteSigned -File build.ps1

動作環境

以下の環境で動作を確認しています。
Windows11 Pro(64bit, 22H2)


コメントを残す

メールアドレスが公開されることはありません。