【C#】PDFファイルの作成・編集(PDFSharpCore)

【C#】PDFファイルの作成・編集(PDFSharpCore)

PDFSharpCoreを使用したPDFファイルの作成・編集例をいくつか記載します。
QuestPDFを使用したPDFファイルの作成例については以下に記載しています。
【C#】PDFファイルの作成(QuestPDF)

<確認環境>
Windows10 64bit
Visual Studio 2022
.NET6.0
PDFSharpCore v1.3.49

PDFSharpCoreとは

PdfSharpCoreは.NET Coreに対応したオープンソースライブラリでPDFファイルの作成・編集が行えます。ライセンスはMITで提供されています。PdfSharpCoreは、PdfSharp.XamarinとMigraDocの一部を移植しており、描画はSixLabors.ImageSharp、フォントはSixLabors.Fontsで実装されます。
https://github.com/ststeiger/PdfSharpCore

PDFSharpCoreのインストール

Visual Studio のメニューから[ツール] > [NuGet パッケージマネージャー] > [パッケージマネージャーコンソール] を選択して以下のコマンドを実行します。
Install-Package PDFSharpCore

または、[プロジェクト] > [NuGet パッケージ管理] でPDFSharpCoreを検索してインストールします。
PDFSharpCoreのインストール

PDFファイルにテキストを書き込む

例はPDFファイルにテキスト(文字列)を書き込みます。

コード
using PdfSharpCore.Pdf;
using PdfSharpCore.Drawing;

// PDFドキュメント作成
var document = new PdfDocument();

// ページ追加
var page = document.AddPage();
page.Size = PdfSharpCore.PageSize.B4;

// 描画オブジェクト取得
var gfx = XGraphics.FromPdfPage(page);

// フォント作成(游明朝)
var font = new XFont("Yu Mincho", 12, XFontStyle.Regular);

// テキスト描画
gfx.DrawString("おはよう!", font, XBrushes.Black,
    new XRect(12, 12, page.Width, page.Height), XStringFormats.TopLeft);
gfx.DrawString("こんにちは!!", font, XBrushes.Red,
    new XRect(12, 24, page.Width, page.Height), XStringFormats.TopLeft);
gfx.DrawString("こんばんは!!!", font, XBrushes.Blue,
    new XRect(12, 36, page.Width, page.Height), XStringFormats.TopLeft);

// PDFファイルの保存
document.Save(@"C:\work\Test.pdf");

PDFの出力結果
PDFSharpCoreのテキスト

フォント設定

任意のフォントを利用するには、IFontResolverを継承したクラスを作成してフォントソルバーに登録します。作成するクラスでフォントのTTFファイル読み込みます。

任意のフォント(TTFファイル)
フォントファイルをフォルダに配置します。
PDFSharpCoreで利用する任意のフォント
フォントファイルは以下を使用しました。
・解星オプティ:https://free-fonts.jp/kaiseiopti/

コード
例はフォントソルバークラスで任意のフォントを読み込んでいます。
using PdfSharpCore.Pdf;
using PdfSharpCore.Drawing;
using PdfSharpCore.Fonts;

// PDFドキュメント作成
var document = new PdfDocument();

// ページ追加
var page = document.AddPage();
page.Size = PdfSharpCore.PageSize.B4;

// 描画オブジェクト取得
var gfx = XGraphics.FromPdfPage(page);

// フォント作成
GlobalFontSettings.FontResolver = new MyFontResolver(); // 自作したフォントソルバー登録
var font1 = new XFont("解星 春の海", 12, XFontStyle.Regular);
var font2 = new XFont("解星オプティ", 12, XFontStyle.Bold);
var font3 = new XFont("Yu Mincho", 12, XFontStyle.Regular);

// テキスト描画
gfx.DrawString("おはよう!", font1, XBrushes.Black,
    new XRect(12, 12, page.Width, page.Height), XStringFormats.TopLeft);
gfx.DrawString("こんにちは!!", font2, XBrushes.Red,
    new XRect(12, 24, page.Width, page.Height), XStringFormats.TopLeft);
gfx.DrawString("こんばんは!!!", font3, XBrushes.Blue,
    new XRect(12, 36, page.Width, page.Height), XStringFormats.TopLeft);

// PDFファイルの保存
document.Save(@"C:\work\Test.pdf");

// フォントソルバークラス
public class MyFontResolver : IFontResolver
{
    public string DefaultFontName { get; }

    public FontResolverInfo ResolveTypeface(string familyName, bool isBold, bool isItalic)
    {
        // フォントファイル特定
        var fontName = familyName;
        if (fontName.Equals("解星 春の海"))
        {
            if (isBold) {
                fontName = "KaiseiHarunoUmi-Bold.ttf";
            }
            else {
                fontName = "KaiseiHarunoUmi-Regular.ttf";
            }
        }
        else if (fontName.Equals("解星オプティ"))
        {
            if (isBold) {
                fontName = "KaiseiOpti-Bold.ttf";
            }
            else {
                fontName = "KaiseiOpti-Regular.ttf";
            }
        }
        else
        {
            fontName= "yumin.ttf";  // 游明朝フォント
        }

        return new FontResolverInfo(fontName);
    }

    public byte[] GetFont(string faceName)
    {
        // フォントファイルのパス作成
        var faceNamePath = Path.Join(@"C:\work\fonts", faceName);
        try
        {
            return File.ReadAllBytes(faceNamePath);
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
            throw new Exception("No Font File Found - " + faceNamePath);
        }
    }
}

PDFの出力結果
PDFSharpCoreの任意フォントテキスト

PDFファイルに透かし文字を書き込む

例は透明度50%の赤色のブラシで、斜めに透かし文字を書き込みます。

コード
using PdfSharpCore.Pdf;
using PdfSharpCore.Drawing;

// PDFドキュメント作成
var document = new PdfDocument();

// ページ追加
var page = document.AddPage();
page.Size = PdfSharpCore.PageSize.B4;

// 描画オブジェクト取得
var gfx = XGraphics.FromPdfPage(page);

// フォント作成
var font1 = new XFont("Yu Mincho", 12, XFontStyle.Regular);
var font2 = new XFont("Yu Mincho", 36, XFontStyle.Regular);

// テキスト描画
var rect = new XRect(0, 0, page.Width, page.Height);
gfx.DrawString("こんにちは!!", font1, XBrushes.Black, rect, XStringFormats.Center);

// 透かし文字描画
var brush = new XSolidBrush(XColor.FromArgb(50, XColors.Red));  // 透明度50%、赤色
var format = new XStringFormat
{
    Alignment = XStringAlignment.Center,
    LineAlignment = XLineAlignment.Center
};

// 描画範囲を回転する
var matrix = new XMatrix();
matrix.RotateAt(-45, new XPoint(page.Width / 2, page.Height / 2), XMatrixOrder.Append);
gfx.MultiplyTransform(matrix);

gfx.DrawString("社外秘", font2, brush, rect, format);

// PDFファイルの保存
document.Save(@"C:\work\Test.pdf");

PDFの出力結果
PdfSharpCoreの透かし文字

PDFファイルに図形を書き込む

例は線、長方形、三角形、円を書き込んでいます。

コード
using PdfSharpCore.Drawing;
using PdfSharpCore.Pdf;

// PDFドキュメント作成
var document = new PdfDocument();

// ページ追加
var page = document.AddPage();
page.Size = PdfSharpCore.PageSize.A4;

// 描画オブジェクト取得
var gfx = XGraphics.FromPdfPage(page);

// ペン作成
var pen = new XPen(XColors.Black, 2);

// 線を描画
gfx.DrawLine(pen, new XPoint(50, 50), new XPoint(150, 50));

// 長方形を描画
gfx.DrawRectangle(pen, new XSolidBrush(XColors.LightBlue), new XRect(50, 100, 100, 50));

// 三角形を描画
var points = new[] { new XPoint(50, 250), new XPoint(150, 250), new XPoint(100, 200) };
gfx.DrawPolygon(pen, new XSolidBrush(XColors.LightGreen), points, XFillMode.Winding);

// 円を描画
gfx.DrawEllipse(pen, new XSolidBrush(XColors.LightPink), new XRect(50, 300, 100, 50));

// PDFドキュメント保存
document.Save(@"C:\work\Shapes.pdf");

PDFの出力結果
PdfSharpCoreの図形書き込み

PDFファイルにハイパーリンクを設定する

例はPDFファイルに描画した長方形と同じ範囲に、Webサイトへのハイパーリンクを設定します。長方形の座標を指定する'XRect'は左上隅を(0,0)とし、ハイパーリンクの座標を指定する'PdfRectangle'は左下隅を(0,0)とするため注意が必要です。

コード
using PdfSharpCore.Drawing;
using PdfSharpCore.Pdf;
using PdfSharpCore.Pdf.Annotations;

// PDFドキュメント作成
var document = new PdfDocument();

// ページ追加
var page = document.AddPage();
page.Size = PdfSharpCore.PageSize.A4;

// 描画オブジェクト取得
var gfx = XGraphics.FromPdfPage(page);

// ボタンを描画(長方形&テキストの描画)
var rect = new XRect(12, 12, 120, 24);
gfx.DrawRectangle(new XPen(XColors.Black, 1), new XSolidBrush(XColors.LightBlue), rect);  // 長方形の描画
var font = new XFont("Yu Mincho", 12, XFontStyle.Bold);
gfx.DrawString(@"ハイパーリンク", font, XBrushes.Black, rect, XStringFormats.Center);     // テキストの描画

// ハイパーリンク設定
// PdfRectangleは左下隅を座標(0,0)、XRectは左上隅を座標(0,0)と扱うため変換
var pdfRect = new PdfRectangle(new XRect(rect.X, page.Height - rect.Y - rect.Height, rect.Width, rect.Height));
var link = PdfLinkAnnotation.CreateWebLink(pdfRect, @"https://ma-noblog.blogspot.com/");
page.Annotations.Add(link);

// PDFドキュメント保存
document.Save(@"C:\work\HyperLink.pdf");

PDFの出力結果
ボタンにカーソルをおくとハイパーリンクが表示されます。クリックするとリンク先に移動します。
PdfSharpCore_ハイパーリンク

PDFファイルに画像を埋め込む

例は画像サイズを20分の1にして埋め込んでいます。

コード
using PdfSharpCore.Pdf;
using PdfSharpCore.Drawing;

// PDFドキュメント作成
var document = new PdfDocument();

// ページ追加
var page = document.AddPage();
page.Size = PdfSharpCore.PageSize.B4;

// 描画オブジェクト取得
var gfx = XGraphics.FromPdfPage(page);

// 画像の埋め込み
var image = XImage.FromFile(@"C:\work\cat.png");
double posX = 12.0;  // 画像位置 X座標
double posY = 12.0;  // 画像位置 Y座標
var newWidth = image.PixelWidth / 20;   // 画像サイズ調整 幅
var newHeight = image.PixelHeight / 20; // 画像サイズ調整 高さ
gfx.DrawImage(image, posX, posY, newWidth, newHeight);

// PDFファイルの保存
document.Save(@"C:\work\Test.pdf");

PDFの出力結果
PdfSharpCore_画像埋め込み

PDFファイルの結合

例は3つのPDFファイルを1つのPDFファイルに結合します。

コード
using PdfSharpCore.Pdf;
using PdfSharpCore.Pdf.IO;

// 結合するPDFファイルパス
var pdfFiles = new string[] { @"C:\work\Test01.pdf", @"C:\work\Test02.pdf", @"C:\work\Test03.pdf" };

// PDFドキュメント作成
var outputDocument = new PdfDocument();

// 結合するPDFファイルを順番に追加
foreach (var pdfFile in pdfFiles)
{
    // PDFファイルを開く
    var inputDocument = PdfReader.Open(pdfFile, PdfDocumentOpenMode.Import);

    // 結合するPDFファイルのページを出力PDFファイルに追加
    foreach (PdfPage page in inputDocument.Pages)
    {
        outputDocument.AddPage(page);
    }
}

// PDFファイルを保存
outputDocument.Save(@"C:\work\Output.pdf");

PDFファイルの分割

例はページ数が均等になるように3つのPDFファイルに分割します。

コード
using PdfSharpCore.Pdf;
using PdfSharpCore.Pdf.IO;

// 分割後のPDFファイルパス
var outputFiles = new string[] { @"C:\work\Test01.pdf", @"C:\work\Test02.pdf", @"C:\work\Test03.pdf" };

// 分割元のPDFファイルを開く
using (var inputDocument = PdfReader.Open(@"C:\work\Input.pdf", PdfDocumentOpenMode.Import))
{
    var outputFileCount = outputFiles.Count();
    var inputPageCount = inputDocument.PageCount;

    // 分割後のページ数を算出
    var outputPageCounts = new int[outputFileCount];   // 各ファイルのページ数
    var quotient = inputPageCount / outputFileCount;   // 商
    var remainder = inputPageCount % outputFileCount;  // 余り
    for (var i = 0; i < outputFileCount; i++)
    {
        // 余りを均等に割り振る
        outputPageCounts[i] = quotient;
        if (0 < remainder) {
            outputPageCounts[i]++;
            remainder--;
        }
        else {
            break;
        }
    }

    // PDFファイルを分割
    var startPage = 0;
    for (var i = 0; i < outputFileCount; i++)
    {
        // 分割後のPDFファイル作成
        PdfDocument outputDocument = new PdfDocument();

        // ページを追加
        for (var j = startPage; j < startPage + outputPageCounts[i]; j++)
        {
            outputDocument.AddPage(inputDocument.Pages[j]);
        }

        // 分割後のPDFファイルを保存
        outputDocument.Save(outputFiles[i]);
        startPage += outputPageCounts[i];
    }
}


Next Post Previous Post