PowershellでZIPファイルをPDFファイルに変換する

コンピュータ

はじめに

このスクリプトは画像ファイル(.jpg.png)を含むZIPファイルをPDFファイルに変換します。

PowerShellスクリプトを初めて実行する場合

PowerShellスクリプトの実行を許可してください。
Powershellのps1ファイルを実行する方法
PowersehllをはじめるにあたりWindowsのコマンドラインインターフェースであるPowershellはコマンドレットと言われる命令をテキストファイルに記述したスクリプトファイルを実行することが出来ます。Powershellはその名...

iTextSharpのインストール

PowershellでPDFファイルを操作するためにiTextSharpをインストールします。
https://github.com/itext/itextsharp/releases/download/5.5.11/itextsharp-all-5.5.11.zipからファイルダウンロードしてください。
ダウンロードしたitextsharp-all-5.5.11.zipを展開し、展開されたファイルitextsharp-all-5.5.11.zipをさらに展開するとitextsharp.dllとiTextSharp.xmlが展開されます。
このファイルをユーザードキュメントフォルダ内にModlue/pdfフォルダを作成しコピーしてください。
以下一連の作業をスクリプト化してみました。

    <#
# itextsharp.dllをインストールします。
#
# インストール先はDocumentsフォルダ下のModules\pdf
#
# ファイル名:Install-iTextSharp.ps1
#>

[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12;

$src_uri = "https://github.com/itext/itextsharp/releases/download/5.5.11/itextsharp-all-5.5.11.zip"
$dst_zip = ".\itextsharp-all-5.5.11.zip"
$documents_dir = (Join-Path $env:USERPROFILE "\Documents")

# githubからダウンロード
Invoke-WebRequest -Uri $src_uri -Outfile $dst_zip

if (!(Test-Path -Path $dst_zip)) {
    echo "zipファイルのダウンロードに失敗しました。";
    exit;
}

# 展開用一時フォルダの作成
$temp_dir1 = New-TemporaryFile | %{ rm $_; mkdir $_ }

# zipファイルを展開
Expand-Archive -Path $dst_zip -DestinationPath $temp_dir1.FullName

$dst_zip2 = Join-Path $temp_dir1 "itextsharp-dll-core.zip"
if (!(Test-Path -Path $dst_zip2)) {
    echo "zipファイルの展開に失敗しました。";
    exit;
}

# 展開用一時フォルダの作成
$temp_dir2 = New-TemporaryFile | %{ rm $_; mkdir $_ }

# zipファイルを展開
Expand-Archive -Path $dst_zip2 -DestinationPath $temp_dir2.FullName


# モジュールフォルダの確認
$modules_dir = Join-Path $documents_dir "Modules"
if (!(Test-Path $modules_dir)) {
    mkdir $modules_dir
} 

# PDFフォルダの作成
$install_dir = Join-Path $modules_dir "pdf"
if (!(Test-Path $install_dir)) {
    mkdir $install_dir
}

Copy-Item (Join-Path $temp_dir2.FullName "*.*") $install_dir

# 後始末
Remove-Item -Path $dst_zip
Remove-Item -Path $temp_dir1  -Recurse -Force;
Remove-Item -Path $temp_dir2  -Recurse -Force;


  

スクリプトのソース

    <#
# 画像ファイルをPDFファイルに変換する
#
# ファイル名:Conv-ZipToPDF.ps1
# 
# 引数:
# SourcePath...変換元のZIPファイルまたはZIPファイルを含むディレクトリのパスを指定
# DestinationPath...変換先のディレクトリを指定
# Recurse...-Recurseを選択すると$DestinationPathディレクトリを再帰的に検索します
#>

param(
    [string]
    $SourcePath,
    [string]
    $DestinationPath=".",
    [switch]
    $Recurse

)

[void][System.Reflection.Assembly]::LoadFrom((Join-Path $env:USERPROFILE "/Documents/Modules/pdf/itextsharp.dll"));

# 画像変換
function Conv-ImageToPDF
{
    param(
        [Parameter(ValueFromPipeline=$true,Mandatory=$true)]
        [string]
        $SrcX,
        [string]
        $DstX
    );
    begin
    {
        $stream = [System.IO.FileStream]::new($DstX, [System.IO.FileMode]::Create, [System.IO.FileAccess]::Write, [System.IO.FileShare]::ReadWrite + [System.IO.FileShare]::Delete);
    }
    process
    {
        $image = [iTextSharp.text.Image]::GetInstance($SrcX);
        $pagesize = New-Object iTextSharp.text.Rectangle($image.Width, $image.Height);
        
        $doc = New-Object iTextSharp.text.Document($pagesize);
        $writer = [iTextSharp.text.pdf.PdfWriter]::GetInstance($doc, $stream);


        $doc.Open();
        $image.SetAbsolutePosition(0, 0);
        [void]$doc.Add($image);
        $doc.Close();
    }
    end
    {
        $stream.Close();
    }
}

# PDF連結
function Join-PDF
{
    param(
        [Parameter(ValueFromPipeline=$true,Mandatory=$true)]
        [string]
        $SrcDir,
        [string]
        $DstPDF
    );
    begin
    {
        echo $DstPDF;
        $stream = [System.IO.FileStream]::new($DstPDF, [System.IO.FileMode]::Create, [System.IO.FileAccess]::Write, [System.IO.FileShare]::ReadWrite + [System.IO.FileShare]::Delete);
        $doc = New-Object iTextSharp.text.Document;
        $writer = New-Object iTextSharp.text.pdf.PdfCopy($doc, $stream);
        $doc.Open();
    }
    process
    {
        Get-ChildItem -Path $SrcDir -Recurse | where {
            $_.Extension -eq ".pdf"
        } | foreach {
            echo $_.FullName;
            $reader = New-Object iTextSharp.text.pdf.PdfReader($_.FullName);
            $page = $writer.GetImportedPage($reader, 1);
            $writer.AddPage($page);
            $reader.Close();
        }
    }
    end
    {
        $writer.Close();
        $doc.Close();
        $stream.Close();
    }
}

# 重複しないファイル名を生成
function Create-UniquePath
{
    param(
        [Parameter(ValueFromPipeline=$true,Mandatory=$true)]
        [string]$BasePath
    )
    begin
    {
    }
    process
    {
        if (!(Test-Path -Path $BasePath)) {
            return $BasePath;
        }
        $f = Get-Item -Path $BasePath;
        $Result = $BasePath;
        for($i=1; (Test-Path -Path $Result); $i++) {
            $Result = $f.Directory.FullName + "/" + $f.BaseName + "(" + $i + ")" + $f.Extension;
        }
        return $Result;
    }
    end
    {
    }
}

# ZIPファイル内の画像ファイルをPDFに変換する
function Conv-ZipToPDF
{
    param(
        [Parameter(ValueFromPipeline=$true,Mandatory=$true)]
        [string]
        $Src,
        [string]
        $Dst
    )
    begin
    {
        $TmpFolder = New-TemporaryFile | %{ rm $_; mkdir $_ }
        echo $TmpFolder.FullName
    }
    process
    {
        Expand-Archive -Path $Src -DestinationPath $TmpFolder
        Get-ChildItem -Path $TmpFolder -Recurse | where {
            $_.Extension -eq '.jpg' -Or $_.Extension -eq '.png'
        } | foreach {
            $s = $_.FullName
            $d = Join-Path $_.Directory.FullName ($_.BaseName + '.pdf')
            Conv-ImageToPDF -Src $s -Dst $d
        }
        Join-PDF -SrcDir $TmpFolder.FullName -DstPDF $Dst
    }
    end
    {
        Get-ChildItem $TmpFolder -Recurse | ForEach-Object {Remove-Item -Path $_.FullName};
        Remove-Item -Path $TmpFolder -Recurse -Force;
    }
}

if (!($SourcePath) -Or !(Test-Path -Path $SourcePath)) {
    echo ($SourcePath+"ファイルが存在しない。");
    exit;
}
$s = Get-Item -Path $SourcePath;

if (!($DestinationPath) -Or !(Test-Path -Path $DestinationPath)) {$DestinationPath = "."}

if ($s.Attributes -eq "Directory") {
    # ディレクトリモード
    
    if ($Recurse) {
        Get-ChildItem -Path $SourcePath -Recurse | where  {
            $_.Extension -eq ".zip"
        } | foreach {
            $ss = $_.FullName
            $dd = Create-UniquePath (Join-Path $DestinationPath ($_.BaseName + '.pdf'))
            Conv-ZipToPDF -Src $ss -Dst $dd
        }
    } else {
        Get-ChildItem -Path $SourcePath | where  {
            $_.Extension -eq ".zip"
        } | foreach {
            $ss = $_.FullName
            $dd = Create-UniquePath (Join-Path $DestinationPath ($_.BaseName + '.pdf'))
            Conv-ZipToPDF -Src $ss -Dst $dd
        }
    }
} else {
    # ファイルモード
    $dd = Create-UniquePath (Join-Path $DestinationPath ($s.BaseName + '.pdf'))
    Conv-ZipToPDF -Src $SourcePath -Dst $dd
}
  

スクリプトの使い方

PowerShellから実行

PS>.\Conv-ZipToPDF.ps1 "変換元のZIPファイルまたはディレクトリ" "変換先のディレクトリ" [-Recurse]

スクリプトの実行環境

プロダクト名
Windows 7 Professional
ビルド番号
7601.23934
Powershellバージョン
5.1.14409.1005
.NET Framework
.NET Framework 4.7

スポンサーリンク


コメント