ClosedXmlでセルの書式を設定してみた(1)

2023年9月3日

どもです。

今回は、ClosedXmlを使用して、Excelのセルの書式を指定する方法について書きます。

0. 作業環境

今回のエントリでは、以下の環境で作業を行います。

開発環境
項目 内容
OS Windows10 Pro(22H2)
CPU i7-8700
メモリ 16GB
IDE Visual Studio Commnuity 2022(64bit)
version 17.7.1
対象のフレームワーク .NET Framework 4.8.1
ClosedXml 0.102.0

1. やってみる内容

今回は、ClosedXmlを用いてセルに罫線を引くということに挑戦してみます。

より具体的に書くと、

「セルの書式設定」ダイアログ中の「罫線」タブで設定可能な内容を、ClosedXmlから設定する

ということを行います。

2. やってみる

2.1. 基本事項

まず基本事項です。

ClosedXmlでセルに罫線を設定する方法は、大きく以下の2つがあります。

  • プロパティに罫線を設定する方法
  • メソッドを使用する方法

プロパティに設定する方法では、IXMLWorkSheetオブジェクトのXxxBorderプロパティに罫線のスタイルを設定します。

対してメソッドを使用する方法では、IXMLWorkSheetオブジェクトのSetXxxBorderメソッドに罫線のスタイルを設定します。

「Xxx」には、罫線を引く場所が入ります。すなわち、「Top」「Bottom」「Left」「Right」「Outside」「Inside」です。

また、各プロパティあるいはメソッドで指定する罫線の種類は、ClosedXmlにおいて、以下のように定義されています。

namespace ClosedXML.Excel
	{
		public enum XLBorderStyleValues
		{
			DashDot,
			DashDotDot,
			Dashed,
			Dotted,
			Double,
			Hair,
			Medium,
			MediumDashDot,
			MediumDashDotDot,
			MediumDashed,
			None,
			SlantDashDot,
			Thick,
			Thin
		}
	}

実際にセルに罫線を設定するためのコードは、以下のようになります。今回は、メソッドを使用して設定しています。

public void Draw1()
{
	using (var workbook = new XLWorkbook())
	{
		var workSheet = workbook.Worksheets.Add(Sheet);

		//セルの周りに標準の罫線を引
		workSheet.Cell(2, 2).Style
			.Border.SetTopBorder(XLBorderStyleValues.DashDot)
			.Border.SetRightBorder(XLBorderStyleValues.DashDot)
			.Border.SetBottomBorder(XLBorderStyleValues.DashDot)
			.Border.SetLeftBorder(XLBorderStyleValues.DashDot);
		workSheet.Cell(2, 2).Value = "XLBorderStyleValues.DashDot";

		workSheet.Cell(2, 4).Style
			.Border.SetTopBorder(XLBorderStyleValues.DashDotDot)
			.Border.SetRightBorder(XLBorderStyleValues.DashDotDot)
			.Border.SetBottomBorder(XLBorderStyleValues.DashDotDot)
			.Border.SetLeftBorder(XLBorderStyleValues.DashDotDot);
		workSheet.Cell(2, 4).Value = "XLBorderStyleValues.DashDotDot";

		workSheet.Cell(4, 2).Style
			.Border.SetTopBorder(XLBorderStyleValues.Dashed)
			.Border.SetRightBorder(XLBorderStyleValues.Dashed)
			.Border.SetBottomBorder(XLBorderStyleValues.Dashed)
			.Border.SetLeftBorder(XLBorderStyleValues.Dashed);
		workSheet.Cell(4, 2).Value = "XLBorderStyleValues.Dashed";

		workSheet.Cell(4, 4).Style
			.Border.SetTopBorder(XLBorderStyleValues.Dotted)
			.Border.SetRightBorder(XLBorderStyleValues.Dotted)
			.Border.SetBottomBorder(XLBorderStyleValues.Dotted)
			.Border.SetLeftBorder(XLBorderStyleValues.Dotted);
		workSheet.Cell(4, 4).Value = "XLBorderStyleValues.Dotted";

		workSheet.Cell(6, 2).Style
			.Border.SetTopBorder(XLBorderStyleValues.Double)
			.Border.SetRightBorder(XLBorderStyleValues.Double)
			.Border.SetBottomBorder(XLBorderStyleValues.Double)
			.Border.SetLeftBorder(XLBorderStyleValues.Double);
		workSheet.Cell(6, 2).Value = "XLBorderStyleValues.Double";

		workSheet.Cell(6, 4).Style
			.Border.SetTopBorder(XLBorderStyleValues.Hair)
			.Border.SetRightBorder(XLBorderStyleValues.Hair)
			.Border.SetBottomBorder(XLBorderStyleValues.Hair)
			.Border.SetLeftBorder(XLBorderStyleValues.Hair);
		workSheet.Cell(6, 4).Value = "XLBorderStyleValues.Hair";

		workSheet.Cell(8, 2).Style
			.Border.SetTopBorder(XLBorderStyleValues.Medium)
			.Border.SetRightBorder(XLBorderStyleValues.Medium)
			.Border.SetBottomBorder(XLBorderStyleValues.Medium)
			.Border.SetLeftBorder(XLBorderStyleValues.Medium);
		workSheet.Cell(8, 2).Value = "XLBorderStyleValues.Medium";

		workSheet.Cell(8, 4).Style
			.Border.SetTopBorder(XLBorderStyleValues.MediumDashDot)
			.Border.SetRightBorder(XLBorderStyleValues.MediumDashDot)
			.Border.SetBottomBorder(XLBorderStyleValues.MediumDashDot)
			.Border.SetLeftBorder(XLBorderStyleValues.MediumDashDot);
		workSheet.Cell(8, 4).Value = "XLBorderStyleValues.MediumDashDot";

		workSheet.Cell(10, 2).Style
			.Border.SetTopBorder(XLBorderStyleValues.MediumDashDotDot)
			.Border.SetRightBorder(XLBorderStyleValues.MediumDashDotDot)
			.Border.SetBottomBorder(XLBorderStyleValues.MediumDashDotDot)
			.Border.SetLeftBorder(XLBorderStyleValues.MediumDashDotDot);
		workSheet.Cell(10, 2).Value = "XLBorderStyleValues.MediumDashDotDot";

		workSheet.Cell(10, 4).Style
			.Border.SetTopBorder(XLBorderStyleValues.MediumDashed)
			.Border.SetRightBorder(XLBorderStyleValues.MediumDashed)
			.Border.SetBottomBorder(XLBorderStyleValues.MediumDashed)
			.Border.SetLeftBorder(XLBorderStyleValues.MediumDashed);
		workSheet.Cell(10, 4).Value = "XLBorderStyleValues.MediumDashed";

		workSheet.Cell(12, 2).Style
			.Border.SetTopBorder(XLBorderStyleValues.None)
			.Border.SetRightBorder(XLBorderStyleValues.None)
			.Border.SetBottomBorder(XLBorderStyleValues.None)
			.Border.SetLeftBorder(XLBorderStyleValues.None);
		workSheet.Cell(12, 2).Value = "XLBorderStyleValues.None";

		workSheet.Cell(12, 4).Style
			.Border.SetTopBorder(XLBorderStyleValues.SlantDashDot)
			.Border.SetRightBorder(XLBorderStyleValues.SlantDashDot)
			.Border.SetBottomBorder(XLBorderStyleValues.SlantDashDot)
			.Border.SetLeftBorder(XLBorderStyleValues.SlantDashDot);
		workSheet.Cell(12, 4).Value = "XLBorderStyleValues.SlantDashDot";

		workSheet.Cell(14, 2).Style
			.Border.SetTopBorder(XLBorderStyleValues.Thick)
			.Border.SetRightBorder(XLBorderStyleValues.Thick)
			.Border.SetBottomBorder(XLBorderStyleValues.Thick)
			.Border.SetLeftBorder(XLBorderStyleValues.Thick);
		workSheet.Cell(14, 2).Value = "XLBorderStyleValues.Thick";

		workSheet.Cell(14, 4).Style
			.Border.SetTopBorder(XLBorderStyleValues.Thin)
			.Border.SetRightBorder(XLBorderStyleValues.Thin)
			.Border.SetBottomBorder(XLBorderStyleValues.Thin)
			.Border.SetLeftBorder(XLBorderStyleValues.Thin);
		workSheet.Cell(14, 4).Value = "XLBorderStyleValues.Thin";

		workbook.SaveAs(Path);
	}
}

先頭と末尾のClosedXmlオブジェクトの生成とファイルへの保存処理は、ココでは重要ではないため読み流してください。

この関数を実行結果(ブックおよびシート)は、以下のようになります。



ClosedXmlのenumの順番と「セルの書式設定」ダイアログの[線]-[スタイル(S):]内の順番が一致していないため、ちょっと対応が分かりにくくなってしまっています。ご容赦ください。

2.2. 範囲の指定

先出のコードでは、1つのセルに対して罫線を設定しています。次は、複数のセルに対して罫線を設定してみます。範囲を指定して罫線を設定する場合は、IXLWorksheetの「Cell」ではなく「Range」プロパティからIXLRangeオブジェクトを取得、罫線を設定します。コードは以下です。

public void Draw2()
{
	using (var workbook = new XLWorkbook())
	{
		var workSheet = workbook.Worksheets.Add(Sheet);

		//複数のセルに罫線を引く
		var firstCell = workSheet.Cell(2, 2);
		var lastCell = workSheet.Cell(4, 4);

		workSheet.Range(firstCell, lastCell).Style
			.Border.SetTopBorder(XLBorderStyleValues.DashDot)
			.Border.SetRightBorder(XLBorderStyleValues.DashDot)
			.Border.SetBottomBorder(XLBorderStyleValues.DashDot)
			.Border.SetLeftBorder(XLBorderStyleValues.DashDot);

		workbook.SaveAs(Path);
	}
}

この処理の実行結果は、下図のようになります。



このように、選択した範囲の「Border」プロパティ/オブジェクトのSetXxxBorderメソッドを使用した場合、「選択した範囲の各セルに対して、指定された罫線を設定」します。

2.3. 範囲の指定(外側/内側)

先述のコードにより、選択した各セルに対して罫線を設定できることは分かりました。しかし一般的に、

選択した範囲のセルの周囲に罫線を引く

とした場合、下図の結果をイメージ/期待すると思います。先の結果とは異なります。



このような罫線は、SetOutsideBorderメソッドを使用します。具体的なコードは、以下です。

public void Draw3()
{
	using (var workbook = new XLWorkbook())
	{
		var workSheet = workbook.Worksheets.Add(Sheet);

		//複数のセルに罫線を引く
		var firstCell = workSheet.Cell(2, 2);
		var lastCell = workSheet.Cell(4, 4);

		workSheet.Range(firstCell, lastCell).Style
			.Border.SetOutsideBorder(XLBorderStyleValues.DashDot);

		workbook.SaveAs(Path);
	}
}

このコードを実行することで、期待する罫線が設定されます。

また、選択範囲の内側のみに罫線を設定する場合には、SetInsideBorderメソッドを使用します。

2.4. 斜めの罫線

最後に、セルに斜めの罫線を設定する方法です。

セルに斜めの罫線を設定する際には、設定する罫線の方向によって使用する関数が異なります。即ち、

  • 左上から右下の場合

    • SetDiagonalBorder
    • SetDiagonalDown
  • 左下から右上の場合

    • SetDiagonalBorder
    • SetDiagonalUp

となります。

実際に、これらのメソッドを使用して斜めの罫線を設定するコードは、以下になります。

public void Draw4()
{
	using (var workbook = new XLWorkbook())
	{
		var workSheet = workbook.Worksheets.Add(Sheet);

		//セルに罫線を引く
		workSheet.Cell(2, 2).Style
			.Border.SetDiagonalBorder(XLBorderStyleValues.Thin)
			.Border.SetDiagonalDown(true);

		//セルに罫線を引く
		workSheet.Cell(3, 2).Style
			.Border.SetDiagonalBorder(XLBorderStyleValues.Thick)
			.Border.SetDiagonalUp(true);

		workbook.SaveAs(Path);
	}
}

このコードを実行した結果は下図です。



3. まとめ

今回は、CLosedXmlを用いてセルに罫線を設定してみました。結果として、IXLSheetのセル(Cell)あるいは選択範囲(IXLRange)のプロパティ、あるいはメソッドを使用することで設定できることが分かりました。勿論、使用する関数によって設定される罫線は異なります。そのため、目的に適した関数を使用する必要があります(…当たり前ですね…)。

次は、セルの結合か、色の設定について書いてみます。

この内容が、誰かの助けになれば幸いです。ではっ!

Ex.

今回のエントリの中で紹介しているコードは、全てGitHubにて公開しています。必要に応じて、参照してください。