【.NET/C#】PDFファイルを作る【PdfSharp】
.NETでPdfSharpを使ってPDFファイルを作りたい!
概要
今回の記事では、.NETでPdfSharpを使ってPDFファイルを作る手順を掲載する。
仕様書
環境
- NET 8.0
- PdfSharp 6.1.1
手順書
NuGetパッケージマネージャーなどからPdfSharp
をインストールする。
Install-Package PdfSharp
日本語のフォントを読み込んで、日本語のテキストが含まれるPDFをエクスポートする例。
日本語のフォントは上記URLのIBM Plex Sans JPと源真ゴシックを使わせてもらった。
using PdfSharp.Drawing;
using PdfSharp.Fonts;
using PdfSharp.Pdf;
using System.Runtime.InteropServices;
namespace tests
{
public class FontResolver : IFontResolver
{
public FontResolver() { }
public byte[] GetFont(string faceName)
{
using (var stream = File.OpenRead(faceName))
{
var data = new byte[stream.Length];
stream.Read(data, 0, data.Length);
return data;
}
}
public FontResolverInfo ResolveTypeface(string familyName, bool isBold, bool isItalic)
{
switch (familyName)
{
case "源真ゴシック":
return new FontResolverInfo("GenShinGothic-Regular.ttf", isBold, isItalic);
case "IBM Plex Sans JP":
default:
return new FontResolverInfo("IBMPlexSansJP-Regular.ttf", isBold, isItalic);
}
}
}
internal class Program
{
static public void ExportPDF1()
{
using (var pdf = new PdfDocument())
{
// PDFにページを追加
PdfPage page = pdf.AddPage();
// ページのサイズを設定
page.Size = PdfSharp.PageSize.A4;
// ページの向き
page.Orientation = PdfSharp.PageOrientation.Portrait;
// ページから描写に使うクラスをインスタンス化
var gfx = XGraphics.FromPdfPage(page);
// FontResolverから文字列描写に使うフォントを作る。フォント、スタイルごとに必要になる
var fontResolver = new FontResolver();
GlobalFontSettings.FontResolver = fontResolver;
var font1Regular = new XFont("IBM Plex Sans JP", 32, XFontStyleEx.Regular);
var font1Bold = new XFont("IBM Plex Sans JP", 32, XFontStyleEx.Bold);
var font1Italic = new XFont("IBM Plex Sans JP", 32, XFontStyleEx.Italic);
var font1BoldItalic = new XFont("IBM Plex Sans JP", 32, XFontStyleEx.BoldItalic);
var font1Strikeout = new XFont("IBM Plex Sans JP", 32, XFontStyleEx.Strikeout);
var font2Regular = new XFont("源真ゴシック", 32, XFontStyleEx.Regular);
var font2Bold = new XFont("源真ゴシック", 32, XFontStyleEx.Bold);
var font2Italic = new XFont("源真ゴシック", 32, XFontStyleEx.Italic);
var font2BoldItalic = new XFont("源真ゴシック", 32, XFontStyleEx.BoldItalic);
var font2Strikeout = new XFont("源真ゴシック", 32, XFontStyleEx.Strikeout);
double offsetX1 = 20;
double offsetX2 = page.Width.Value - (offsetX1 * 2);
double offsetY = 20;
double lineHeight = 52;
// 文字列を描写
gfx.DrawString("PDFテスト", font1Regular, XBrushes.Black, new XRect(offsetX1, offsetY, offsetX2, lineHeight), XStringFormats.TopLeft);
gfx.DrawString("Regular", font1Regular, XBrushes.Black, new XRect(offsetX1, offsetY + (lineHeight * 1), offsetX2, lineHeight), XStringFormats.TopLeft);
gfx.DrawString("Bold", font1Bold, XBrushes.Black, new XRect(offsetX1, offsetY + (lineHeight * 2), offsetX2, lineHeight), XStringFormats.TopLeft);
gfx.DrawString("Italic", font1Italic, XBrushes.Black, new XRect(offsetX1, offsetY + (lineHeight * 3), offsetX2, lineHeight), XStringFormats.TopLeft);
gfx.DrawString("BoldItalic", font1BoldItalic, XBrushes.Black, new XRect(offsetX1, offsetY + (lineHeight * 4), offsetX2, lineHeight), XStringFormats.TopLeft);
gfx.DrawString("Strikeout", font1Strikeout, XBrushes.Black, new XRect(offsetX1, offsetY + (lineHeight * 5), offsetX2, lineHeight), XStringFormats.TopLeft);
gfx.DrawString("Regular", font2Regular, XBrushes.Black, new XRect(offsetX1, offsetY + (lineHeight * 6), offsetX2, lineHeight), XStringFormats.TopLeft);
gfx.DrawString("Bold", font2Bold, XBrushes.Black, new XRect(offsetX1, offsetY + (lineHeight * 7), offsetX2, lineHeight), XStringFormats.TopLeft);
gfx.DrawString("Italic", font2Italic, XBrushes.Black, new XRect(offsetX1, offsetY + (lineHeight * 8), offsetX2, lineHeight), XStringFormats.TopLeft);
gfx.DrawString("BoldItalic", font2BoldItalic, XBrushes.Black, new XRect(offsetX1, offsetY + (lineHeight * 9), offsetX2, lineHeight), XStringFormats.TopLeft);
gfx.DrawString("Strikeout", font2Strikeout, XBrushes.Black, new XRect(offsetX1, offsetY + (lineHeight * 10), offsetX2, lineHeight), XStringFormats.TopLeft);
// 線を描写
gfx.DrawLine(XPens.Black, offsetX1, offsetY + 48, page.Width.Value - offsetX1, offsetY + 48);
// 線の色と太さを指定して描写
var pen = new XPen(XColor.FromArgb(0xFFFF00FF), 16);
gfx.DrawLine(pen, offsetX1, page.Height.Value - offsetY, page.Width.Value - offsetX1, page.Height.Value - offsetY);
// 矩形を塗りつぶして、その上に文字列を描写
gfx.DrawRectangle(XBrushes.Black, offsetX1, offsetY + lineHeight * 11, offsetX2, lineHeight);
gfx.DrawString("Text", font1Bold, XBrushes.White, new XRect(offsetX1, offsetY + (lineHeight * 11), offsetX2, lineHeight), XStringFormats.CenterLeft);
// PDFを出力
pdf.Save("test1.pdf");
}
}
static void Main(string[] args)
{
ExportPDF1();
}
}
}
日本語を含む外部のフォントファイル(ttfとか)を使うにはインターフェイスIFontResolver
を継承したクラスを実装して読み込む。
メソッドResolveTypeface
でスタイル(レギュラー、ボールド、イタリックなど)毎に対応したFontResolverInfo
を返すようにする。FontResolverInfo
のコンストラクターでメソッドGetFont
が呼ばれるので第1引数にttfファイルなどのフォントファイルへのパスを渡す。第2引数、第3引数で太字とイタリックのスタイルを1つフォントファイルからエミュレートできる。スタイルによってフォントファイル自体を指定することもできる。
if (isBold)
{
return new FontResolverInfo("IBMPlexSansJP-Bold.ttf", false, isItalic);
}
else
{
return new FontResolverInfo("IBMPlexSansJP-Regular.ttf", false, isItalic);
}
文字列の描写はページに対応したXGraphics
のメソッドDrawString
を使う。XRect
でテキストエリアを指定して、XStringFormats
で文字列の配置方法を指定する感じ。XStringFormats.TopLeft
だと左上寄せ、XStringFormats.CenterpLeft
だと中央左寄せ、垂直、水平の順で位置を指定する感じ。
PdfPage page = pdf.AddPage();
var gfx = XGraphics.FromPdfPage(page);
var fontResolver = new FontResolver();
GlobalFontSettings.FontResolver = fontResolver;
var font = new XFont(
"IBM Plex Sans JP", // FontResolverの中でフォントの判定に使われる文字列
32, // フォントサイズ
XFontStyleEx.Regular // フォントのスタイル
);
gfx.DrawString(
"PDFテスト", // 描写したい文字列
font, // 描写に使うXFont
XBrushes.Black, // フォントの色(XBrushe)
new XRect(
24, // テキストエリアの始点のX座標
32, // Y座標
200, // 幅
96 // 高さ
),
XStringFormats.TopLeft // テキストエイアの中での文字列の位置
);
矩形の描写はメソッドDrawRectangle
を使う。
gfx.DrawRectangle(
XBrushes.Black, // 矩形の色(XBrushe)
24, // 矩形の始点のX座標(XRectと同じ感じ)
32, // Y座標
200, // 幅
96 // 高さ
線の描写にはメソッドDrawLine
を使う。
gfx.DrawLine(
XPens.Black, // 線の色(XPen)
64, // 線の始点のX座標
32, // 線の始点のY座標
256, // 線の終点のX座標
128 // 線の終点のY座標
);
線の色や太さを指定したい場合はXPen
をインスタンス化して使う。
var pen = new XPen(
XColor.FromArgb(0xFFFF00FF), // ARGBで色を指定
16 // 線の太さ
);
まとめ(感想文)
簡単なPDFなら簡単に作れちゃう感じ。