インターネットで調べたプログラミングの知識を備忘録的に一箇所にまとめておく。
Visual C#のプロジェクトでClosedXMLが使用できるようにする。 Visual Studio 2022の場合、メニューバーから、ツール ― NuGetパッケージマネージャー ― パッケージマネージャーコンソールを選んで、パッケージマネージャーコンソールを開く。 そこで以下のように入力して、ClosedXMLをプロジェクト内にインストールする。
install-package closedxml
参考サイト:ClosedXML を用いて Excel ファイルを操作する方法
例として、Excelファイルの最初のシートを読み書きするクラスを作ってみる。 構成は以下のような感じで。
class ExcelFile{
public ExcelFile(string file_name);
public CellData Cell(int row, int column);
public void Save();
private readonly ClosedXML.Excel.XLWorkbook m_book;
private readonly ClosedXML.Excel.IXLWorksheet m_sheet;
private readonly bool m_writable;
}
コンストラクタでファイルを開く。
セルの取得は、本来ならClosedXML.Excel.IXLCell
オブジェクトを使用するのだが、今回はそれをマッピングしたCellData
クラスを実装しようと思う。
m_writable
メンバ変数には、書き込み可能であればtrue
を、不可能(読み込み専用)であればfalse
を設定する。
ファイル名を指定すれば読み書き両方できる指定で開くことができる。 既に当該ファイルを開いているときは、書き込みができないので例外が放出される。 その場合は読み取り専用で開くのだが、その時はファイルストリームを使用する。
public ExcelFile(string file_name)
{
try{
m_book = new ClosedXML.Excel.XLWorkbook(file_name);
m_writable = true;
}
catch{
// ファイルの読み込みに失敗した場合は、読み込み専用で開く。
var file = new System.IO.FileStream(file_name, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.ReadWrite);
m_book = new ClosedXML.Excel.XLWorkbook(file);
file.Close();
m_writable = false;
}
// 最初のシートを読み書きする。1スタートなのに注意。
m_sheet = m_book.WorkSheet(1);
}
参考サイト:他のプロセスで開かれているExcelファイルをClosedXMLで開く ― shuhelohelo's blog
CellDataクラスについては後述。
public ClosedXML.Excel.IXLCell Cell(int row, int column){
return new CellData(m_sheet.Cell(row, column));
}
書き込み不可能な状態で保存すると例外が放出されるので、書き込み可能か確認してから保存する。
public void Save(){
if(m_book != null && m_writeable){
m_book.Save();
}
}
セルを表すClosedXML.Excel.IXLCell
オブジェクトをメンバに含むクラスを自作する。
本当ならばClosedXML.Excel.IXLCell
クラスを直接継承したかったが、インスタンスクラスであり継承すると実装が面倒になる。
class CellData{
public CellData(ClosedXML.Excel.IXLCell cell);
public string Text; // property
private readonly ClosedXML.Excel.IXLCell m_cell;
}
メンバに代入するだけ。
public CellData(ClosedXML.Excel.IXLCell cell)
{
m_cell = cell;
}
GetText
メンバ関数を使用する場合、空欄だと例外が発生する。
例外が発生した場合は空オブジェクトを返すようにする。
public string Text
{
get
{
try{
return m_cell.GetText();
}
catch{
return string.Empty;
}
}
set
{
m_cell.Value = value;
}
}