[C#] PdfSharp で複数の PDF ファイルを結合する (.NET Framework)
今回はオープンソースの PDF ライブラリーである PdfSharp を使って、複数の PDF ファイルを 1 つに結合する方法を紹介します。
環境
- Windows 11
- Visual Studio 2022
- .NET Framework 4.7.2
PdfSharp 採用の背景
オープンソースの PDF ライブラリーでは iTextSharp が有名なのですが、こちらはオープンソース版のライセンスが AGPL です。
AGPL は GPL がベースですので、コピーレフトであり、その著作物を利用するソフトウェアも必然的に同ライセンスにする必要があります(複数の見解あり)。商用のソフトウェアの場合、ソースコードを公開するわけにはいかないため、これは大きな障害になります。
その点、 PdfSharp は MIT ライセンスです。 MIT ライセンスは再頒布時に著作権とライセンスの表示さえすれば、ほぼ自由に扱え、派生物についてはソースコードの公開義務もありません。
よってここでは PdfSharp を使用しました。
PdfSharp のインストール
NuGet パッケージが用意されていますので、 Visual Studio で「NuGet パッケージの管理」を開き、使用するプロジェクトに PdfSharp をインストールするだけです。
PdfSharp で PDF を結合する
インタフェースは非常に簡単です。使うクラスは PDF 文書を扱う PdfDocument
、 PDF を読み取る PdfReader
、 ページを表す PdfPage
のみです。
下記の例では、入力として「複数の PDF ファイルのパス」と「保存先のファイルパス」を渡して、順番に PDF を結合しています。日本語の PDF でも問題なく結合できました。
/// <summary>
/// 複数の PDF ファイルを結合して、指定したファイルパスに保存します。
/// </summary>
/// <param name="sourceFilenames">PDF ファイルのパスのリスト</param>
/// <param name="destinationFilename">保存先のファイルパス</param>
public void MergePdfFiles(IEnumerable<string> sourceFilenames, string destinationFilename)
{
using (PdfDocument document = new PdfDocument())
{
foreach (string filename in sourceFilenames)
{
using (PdfDocument inputDocument = PdfReader.Open(filename, PdfDocumentOpenMode.Import))
{
foreach (PdfPage page in inputDocument.Pages)
{
document.AddPage(page);
}
}
}
document.Save(destinationFilename);
}
}
ざっくりとした流れは下記の通りです。
- 結合した PDF を格納する
PdfDocument
(document
) を生成 - 各 PDF ファイルを開く
- 各ページを
document
に追加 document
をファイルとして保存
実際のアプリケーションで使うときは、進捗表示のためにページや文書ごとにコールバックを呼び出す必要があるかもしれません。
ちなみに C# 9.0 が利用できる場合は using 変数宣言と new 演算子後の型名を省略して下記のようにスッキリ書けます。
/// <summary>
/// 複数の PDF ファイルを結合して、指定したファイルパスに保存します。
/// </summary>
/// <param name="sourceFilenames">PDF ファイルのパスのリスト</param>
/// <param name="destinationFilename">保存先のファイルパス</param>
public void MergePdfFiles(IEnumerable<string> sourceFilenames, string destinationFilename)
{
using PdfDocument document = new();
foreach (string filename in sourceFilenames)
{
using PdfDocument inputDocument = PdfReader.Open(filename, PdfDocumentOpenMode.Import);
foreach (PdfPage page in inputDocument.Pages)
{
document.AddPage(page);
}
}
document.Save(destinationFilename);
}
.NET Core, .NET 5 以降の場合
PdfSharp は 2019 年から更新が止まっており、 .NET Framework 以外には対応していないようです。プロジェクトが .NET Framework でない場合は PdfSharpCore をお試しください。
- ststeiger/PdfSharpCore: Port of the PdfSharp library to .NET Core - largely removed GDI+ (only missing GetFontData - which can be replaced with freetype2)
- PdfSharpCore の紹介