このページには自動翻訳されたテキストを含めることができます。

C# PDF 生成クイック スタート ガイド

.NET プロジェクトでレポート、請求書、領収書などの PDF ファイルを生成する方法についてお読みくださ い。 C# または VB.NET を使用して、構造要素を組み合わせて PDF ドキュメントを簡単に作成します。 要素 には、ヘッダー、フッター、コンテナ、テーブル、段落、画像などが含まれます。 API はコンテンツを自動的 にページに分割します。

PDF ファイルを生成するその他の方法については、C# および VB.NET で PDF ドキュメントを作成す る の記事で説明されています。

PDF生成ライブラリの紹介

レイアウト API は Docotic.Pdf ライブラリの無料のアドオンとして提供されます。 ライブラリとレイアウト アドオンは両方とも、NuGet および当社のサイトから入手できます。 評価モード制 限なしでライブラリを試すには、ライブラリ ページで、期間限定の無料ラ イセンス キーを取得します。

Docotic.Pdf ライブラリ 9.3.17105-dev レイアウトアドオン 9.3.17105-dev
回帰テスト 14,681人が合格 NuGet の合計ダウンロード数 4,234,061

インストール

NuGet から BitMiracle.Docotic.Pdf.Layout パッケージをインストールします。 これは、Layout アドオンを インストールする最も簡単で便利な方法です。

代わりに、当社のサイトで ライブラリ バイナリを含む ZIP をダウンロードすることもでき ます。 Layout API を使用するには、ZIP パッケージから次の DLL への参照を追加します:

  • BitMiracle.Docotic.Pdf.dll
  • Layout add-on/BitMiracle.Docotic.Pdf.Layout.dll

アプローチ

エントリ ポイントは PdfDocumentBuilder クラスです。 PDF の生成を開始するには、クラスの Generate メソッドを呼び出します。 このメソッドには、パラメータの 1 つとして Action<Document> タイプのデリ ゲートが必要です。 ライブラリでは、デリゲート内でドキュメントのコンテンツをレイアウトすることが期待 されています。

PdfDocumentBuilder.Create().Generate("output.pdf", (Document doc) =>
{
    // ここでドキュメントのコンテンツを構築します
});

Document オブジェクトが与えられると、デリゲートはレイアウトを定義する必要があります。 完全なレイ アウトは、より小さな構成要素で構成されます。 ページ、ヘッダーとフッター、コンテナー、テキスト ブ ロックは、そのようなブロックの例です。

多くのメソッド呼び出しが連鎖しています。 チェーン内の呼び出しの順序は重要です。 以下は、いくつかの 連鎖呼び出しでページ コンテンツをセットアップする方法を示す例です。

PdfDocumentBuilder.Create()
    .Generate("output.pdf", doc => doc.Pages(pages =>
    {
        pages.Content().Padding(24).AlignCenter().Text("Some text");
    }));

Intellisense は API の発見に役立ちます。 API を自分で試してみてください。 使いやすいと思っていただ ければ幸いです。

こんにちは世界!

一般的な構成要素の動作を示す単純なアプリケーションを開発してみましょう。 アプリは上記のアプローチを 使用します。

完全なアプリケーション コード を Docotic.Pdf サンプル コード リポジトリに置きま した。 このステップのコードは、サンプル アプリの HelloWorld クラスにあります。

public void CreatePdf()
{
    PdfDocumentBuilder.Create().Generate("hello.pdf", doc => doc.Pages(page =>
    {
        page.Content().Text("Hello, world!");
    }));
}

コードはそれほど多くありませんが、ここで何が起こっているのでしょうか?

ショートコードに対する長い説明

このコードはドキュメント ビルダーのインスタンスを作成し、ビルダーに hello.pdf を生成するように要 求します。 ビルダーは、ドキュメント コンテンツのレイアウトのジョブを私のコードに委任します。

デリゲートのコードで、ドキュメントにいくつかのページを構築するように依頼します。 これで、ドキュメ ントはページのコンテンツをコードにレイアウトする仕事を委任します。

ページのデリゲートで、ページの主要コンテンツのレイアウト コンテナーにアクセスします。 これを行うに は、Content メソッドを呼び出します。 Text への連鎖呼び出しにより、有名なテキスト スパンがページ のコンテンツに追加されます。

ここで、ビルダーは、提供されたレイアウトに従って いくつかの ページを含むドキュメントを生成しま す。 ビルダーは、プライマリ コンテンツのレイアウト コンテナーに追加したデータを含めるのに必要な正確 な数のページを作成します。 この場合、1 ページで十分ですか? わかった。

将来のアップデートに備えて

コードにさらに機能を追加していきます。 アプリをさらに開発しやすくするために、コードを次のように変更 しました。

public void CreatePdf()
{
    PdfDocumentBuilder.Create().Generate("hello.pdf", BuildDocument);
}

static void BuildDocument(Document doc)
{
    doc.Pages(BuildPages);
}

static void BuildPages(PageLayout pages)
{
    pages.Content().Text("Hello, world!");
}

不必要に見えるかもしれませんが、コードをメソッドに分割すると、少なくともコードが読みやすくなりま す。

このステップのサンプル コードは、サンプル アプリHelloWorld2 クラスにありま す。

ドキュメント、ページ、コンテナーの詳細については、次の記事を確認してください。

フォントと色

デフォルトのフォントでも良いですが、別のフォントを使用する方法を紹介します。 主なアイデアは、フォン トを使用してテキスト スタイルを作成することです。 次に、必要に応じて、いくつかのオプションのプロパ ティをスタイルに適用し、最後にテキスト スパンでスタイルを使用します。

オペレーティング システムにインストールされているフォントのコレクションからフォントを使用したり、 ファイルまたはストリームからフォントをロードしたりできます。

ドキュメントのタイポグラフィを設定して、事前定義されたスタイルをオーバーライドすることをお勧めしま す。 ただし、これは必須ではなく、テキスト スタイルを直接使用できます。

このステップのサンプル コードは、サンプル アプリHelloWorld3 クラスにありま す。 以下は、前のステップから変更された部分です。

static void BuildDocument(Document doc)
{
    doc.Typography(t =>
    {
        t.Document = doc.TextStyleWithFont(SystemFont.Family("Calibri"));
    });
    doc.Pages(BuildPages);
}

static void BuildPages(PageLayout pages)
{
    pages.Size(PdfPaperSize.A6);
    pages.Margin(10);

    BuildTextContent(pages.Content());
}

static void BuildTextContent(LayoutContainer content)
{
    var colorAccented = new PdfRgbColor(56, 194, 10);
    var styleAccented = TextStyle.Parent.FontColor(colorAccented);

    content.Text(t =>
    {
        t.Span("Hello, ").Style(styleAccented);
        t.Span("world!").Style(styleAccented.Underline());
    });
}

ご覧のとおり、BuildDocumentBuildPages のコードを更新しました。 BuildTextContent という名 前の新しいメソッドも追加しました。

BuildDocument では、「Calibri」という名前のシステム フォントからテキスト スタイルを作成します。 次に、このテキスト スタイルをドキュメントのデフォルトのテキスト スタイルとして設定します。

BuildPages メソッドには、すべてのページのサイズとマージンを設定するコードが含まれるようになりまし た。 また、このメソッドは BuildTextContent を呼び出し、ページの主要コンテンツのコンテナをパラメー タとして渡します。

主要なコンテンツを構築する方法が現在とは異なります。 2 つのテキスト スパンを使用し、各スパンに異な るテキスト スタイルを適用します。 実際には、両方のスパンでアクセント カラーが使用されますが、2 番目 のスパンにも下線が付けられます。

このコードは、カスタム テキスト フォントと色の PDF を生成します。 結果にトライアルメッセー ジの警告が含まれている場合は、Docotic.Pdf ライブラリ ページで期間限定の無料ライセンスを取得してくだ さい。

レポートや請求書などの実際の PDF ドキュメントの多くには、ヘッダーとフッターが含まれています。 PDFに ヘッダーとフッターを追加する方法を説明します。

このステップのサンプル コードは、サンプル アプリHelloWorld4 クラスにありま す。 以下は、前のステップから変更された部分です。

static void BuildPages(PageLayout pages)
{
    pages.Size(PdfPaperSize.A6);
    pages.Margin(10);

    BuildPagesHeader(pages.Header());
    BuildPagesFooter(pages.Footer());

    BuildTextContent(pages.Content());
}

static void BuildPagesHeader(LayoutContainer header)
{
    header.TextStyle(TextStyle.Parent.FontSize(8))
        .AlignRight()
        .Text(t =>
        {
            t.Line($"Created by: {Environment.UserName}");
            t.Line($"Date: {DateTime.Now}");
        });
}

static void BuildPagesFooter(LayoutContainer footer)
{
    footer.Height(20)
        .Background(new PdfGrayColor(95))
        .AlignCenter()
        .Text(t => t.CurrentPageNumber());
}

ヘッダコンテナをパラメータとして BuildPagesHeader を呼び出すように BuildPages メソッドを変更し ました。 このメソッドはまた、BuildPagesFooter を呼び出してフッター コンテナーを渡します。

結果として得られる ヘッダーとフッターを含む PDF は、間違いなくプロフェッショナ ルな PDF ドキュメントのように見えます。

BuildPagesHeader メソッドは、テキストのフォント サイズを小さく設定します。 ヘッダーの内容には 2 行を使用します。1 行目は現在のユーザーの名前で、2 行目は現在の日付です。 テキストは右揃えになりま す。

ヘッダーのサイズを明示的に指定していないことに注意してください。 左右の余白を除いたページ幅全体を占 めます。 高さはテキスト行の高さによって異なります。

フッターも同様ですが、高さが明示的に指定されている点が異なります。 そして、背景色が適用されます。興 味深いのは、CurrentPageNumber メソッドを 使用するだけで PDF フッターに現在のページ番号を入力できることです。 すべての計算はライブラリ内で行 われます。

画像

よく言われるように、1 枚の写真を使用すると、多くの文字を節約できます。 見積書や領収書では、会社のロ ゴやその他の重要な画像を使用することになるでしょう。 このサンプルコードでは、見栄えの良いものだけを 使用します。

このファイルは私たちのサイトにあります。美しい画像を含む PDFがどのように表示されるかを確認してくださ い。

画像を使用するには、まずそれをドキュメントに追加する必要があります。 ライブラリは、ファイルまたはス トリームからイメージを読み取ることができます。 ドキュメントに画像を追加する方法を示すために BuildDocument メソッドを変更しました。

このステップのサンプル コードは、サンプル アプリHelloWorld5 クラスにありま す。 以下は、前のステップから変更された部分です。

static void BuildDocument(Document doc)
{
    doc.Typography(t =>
    {
        t.Document = doc.TextStyleWithFont(SystemFont.Family("Calibri"));
    });

    var imageFile = new FileInfo("red-flowers-at-butterfly-world.jpg");
    var image = doc.Image(imageFile);

    doc.Pages(pages => {
        BuildPages(pages);

        pages.Content().Column(c =>
        {
            BuildTextContent(c.Item());
            BuildImageContent(c.Item(), image);
        });
    });
}

static void BuildPages(PageLayout pages)
{
    pages.Size(PdfPaperSize.A6);
    pages.Margin(10);

    BuildPagesHeader(pages.Header());
    BuildPagesFooter(pages.Footer());
}

static void BuildImageContent(LayoutContainer content, Image image)
{
    content.AlignCenter()
        .PaddingVertical(20)
        .Image(image);
}

ご覧のとおり、BuildDocument メソッドにはさらに多くの変更があります。 以前は、コードは「Text」メ ソッドを使用して、ページの主要なコンテンツとしてテキストを設定していました。 これは引き続き BuildTextContent メソッドで発生します。 しかし、今度はコンテンツに画像も必要になります。

ページの主要コンテンツにテキストと画像の両方を含めるには、コンテナが必要です。 Columnコンテナを 使ってテキストと画像を縦に順番に追加していきます。 カラムコンテナのItemメソッドはサブコンテナを提 供します。 Item メソッドへの 1 回の呼び出しを使用してテキストのコンテナを取得し、もう 1 回の呼び 出しを使用して画像のコンテナを取得します。

ご覧のとおり、BuildTextContent は少しも変更していません。 ただし、もちろん、BuildPages メソッド から BuildTextContent への呼び出しを削除する必要がありました。

BuildImageContent は 3 行で重要な仕事をします。 画像を上部と下部にパディングして追加します。 ま た、画像がページの中央に配置されます。

リスト

リストとは何ですか? これを、上下に書かれた番号付き項目のグループとして考えてみましょう。 このアイデ アは、リストを実装する方法を提案します。

このステップのサンプル コードは、サンプル アプリHelloWorld6 クラスにありま す。 以下は、前のステップから変更された部分です。

static void BuildDocument(Document doc)
{
    ....

    doc.Pages(pages => {
        BuildPages(pages);

        pages.Content().Column(c =>
        {
            BuildTextContent(c.Item());
            BuildImageContent(c.Item(), image);
            BuildListContent(c.Item());
        });
    });
}

static void BuildListContent(LayoutContainer content)
{
    var dayNames = DateTimeFormatInfo.InvariantInfo.DayNames;
    var dayNamesSpain = DateTimeFormatInfo.GetInstance(new CultureInfo("es-ES")).DayNames;

    content.Column(column =>
    {
        for (int i = 0; i < dayNames.Length; i++)
        {
            column.Item().Row(row =>
            {
                row.Spacing(5);
                row.AutoItem().Text($"{i + 1}.");
                row.RelativeItem().Text(t => {
                    t.Line(dayNames[i]);
                    t.Line($"In Spain they call it {dayNamesSpain[i]}");
                });
            });
        }
    });
}

BuildDocument の唯一の変更点は、新しいメソッド呼び出しです。 BuildImageContent 呼び出しの後に BuildListContent への呼び出しを追加しました。

BuildListContent はリストを行の列として作成します。 各行には 2 つの項目があります。 最初 (左) は 商品番号用です。 もう 1 つ (右) はアイテムのテキスト用です。 このコードは、行内の項目間の間隔を明示 的に設定します。

アイテムを配置するには、Row コンテナが各アイテムのサイズを事前に知っているか、計算する必要があり ます。 この例では AutoItem メソッドと RelativeItem メソッドを使用します。 その結果、行コンテ ナーは最初の項目を含めるのに必要な幅を計算します。 その後、コンテナーは残りの利用可能な幅を 2 番目 の項目に使用します。

リストを追加すると、作成された PDF の内容が 1 ページに収まらなくなりました。 Layout APIは自動的に2 ページ目を追加し、その上にリストを配置します。 API が 複数ページの PDF ドキュメン ト の新しいページでヘッダーとフッターを繰り 返していることがわかります。

テーブル

多くの PDF ドキュメントには表が含まれています。 テーブルはデータの明瞭さと組織化を強化するため、こ れは驚くべきことではありません。 Layout APIを使用してPDFに表を作成する方法を説明します。

このステップのサンプル コードは、サンプル アプリHelloWorld7 クラスにありま す。 以下は、前のステップから変更された部分です。

static void BuildDocument(Document doc)
{
    ....

    doc.Pages(pages => {
        BuildPages(pages);

        pages.Content().Column(c =>
        {
            BuildTextContent(c.Item());
            BuildImageContent(c.Item(), image);
            BuildListContent(c.Item());
            BuildTableContent(c.Item());
        });
    });
}

static void BuildTableContent(LayoutContainer content)
{
    var color = new PdfGrayColor(75);

    content.PaddingTop(20).Table(t =>
    {
        t.Columns(c =>
        {
            c.RelativeColumn(4);
            c.RelativeColumn(1);
            c.RelativeColumn(4);
        });

        t.Header(h =>
        {
            h.Cell().Background(color).Text("Month in 2024");
            h.Cell().Background(color).Text("Days");
            h.Cell().Background(color).Text("First Day");
        });

        for (int i = 0; i < 12; i++)
        {
            var stats = GetMonthStats(2024, i);

            t.Cell().Text(stats.Item1);
            t.Cell().Text(stats.Item2);
            t.Cell().Text(stats.Item3);
        }
    });
}

static (string, string, string) GetMonthStats(int year, int monthIndex)
{
    return (
        DateTimeFormatInfo.InvariantInfo.MonthNames[monthIndex],
        DateTime.DaysInMonth(year, monthIndex + 1).ToString(),
        new DateTime(year, monthIndex + 1, 1).DayOfWeek.ToString()
    );
}

BuildTableContent の呼び出しが BuildDocument の唯一の変更です。

BuildTableContent では、簡単なテーブルを作成します。 このテーブルには、2024 年の月に関する簡単な 情報が表示されます。まず、相対的な幅を持つ 3 つの列を定義します。 左端と右端の列の幅は、中央の列の 4 倍になります。

このコードはテーブルのヘッダーも定義します。 これを行うには、ヘッダー セルを追加し、各セルのテキス トと背景色を指定します。 表が 1 ページに収まらない場合、ヘッダーは表が占める各ページで繰り返されま す。 これは、結果として得られる テーブル付き PDF ドキュメン トで確認できます。 この文書では、表は 2 ページ目から始まり、3 ページ目まで続きます。

単純なループを使用して行を作成しています。 ループ内のコードは、各月に関する情報を取得することから始 まります。 次に、情報の行を構成する 3 つのセルを追加します。

サンプルコード

上記では、C# での PDF 生成の最も一般的な機能のいくつかを紹介しました。 次の記事を読んで API につい てさらに調べてみることをお勧めします。 GitHub の Docotic.Pdf.Samples リポジトリのサンプル コードも 試してください。 Layout APIのサンプルコードはリポジトリのLayoutフォルダにあります。

サンプル コードをコード プレイグラウンドとして使用できます。 こうすることで、毎回最初から始めること なく、いくつかのアイデアを試すことができます。

同じサンプル コードが ZIP パッケージの Samples フォルダーにあります。 ソリューション ファイルは 2 つあります。 SamplesCSharp は、C# 言語を使用したサンプル プロジェクト用です。 SamplesVB.NET は VB.NET バージョン用です。