SpreadSheetLightはC#でエクセル編集可能であるオープンソースのライブラリの1つです。
C#では、SpreadSheetLightの他にClosedXMLやEPPlusといったライブラリが存在しています。筆者としてはSpreadSheetLightよりは前者2つのを優先して採用していますが、特定条件(無償利用可が必須かつグラフ描写が必要な時)についてはSpreadSheetLightを利用させていただいています。
本記事では、その様なライブラリ選定の背景と、基本操作を解説します。尚、C#で利用できるエクセル編集ライブラリの比較については、以下の関連記事で詳しく述べています。
◇目次
SpreadSheetLightの長所と特徴
SpreadSheetLightは2023年6月現在はMITライセンスで提供されており、ライセンス本文を順守の上で商用でも利用することが可能です。(ライセンスについては公式のライセンスページを必ず参照してください。)
同じくMITライセンスでOpenXMLのラッパーであるClosedXMLに比べると読み書き速度が遅いという報告があり、体感としてもClosedXMLの方が早く感じるため、個人的には特定目的がある場合のみ採用するライブラリという位置づけをしています。
2023年6月現在の私の調査による「ClosedXML対応不可でSpreadSheetLightなら実現可能なこと」は次の通りです。
- グラフの作成
- パスワード付きファイルの開閉
これらの対応が必要でEPPlusの有料ライセンスが利用不可の場合は選択肢として有力と考えられます。
入手 - NuGetより導入可能
NuGetでプロジェクトに導入できます。尚、いくつか種類がありますが、.NET環境(.NET7.0等)で利用する場合はSpreadsheetLight.Cross.Platformを選択するようにしましょう。無印SpreadsheetLight等を選択すると、通常では生じないエラーが発生する場合があります。(後述:トラブルシューティング参照)
SpreadSheetLightの基本操作
SpreadSheetLightでは、SLDocumentに現在のスコープを指定してワークシートを編集していきます。
EPPlusやClosedXMLはVBAの文法に近く、ワークブック・ワークシート・セルといったオブジェクトに対して個々のクラスが作成されていますが、SpreadSheetLightの文法はやや毛色が異なります。
ワークブックオブジェクトの生成
SLDocumentクラスをコンストラクタで生成します。新規作成の場合は引数不要、既存ファイルの場合は引数にファイルパスを与えます。
新規作成の場合
C#
//新規作成の場合
var slDocument = new SLDocument();
既存ファイルを開く場合
C#
//既存ファイルを開く場合
var slDocument = new SLDocument(filePath);
ワークシートの作成、選択
SpreadSheetLightでは、新規にSLDocumentを作成した場合、Sheet1という名前のワークシートが自動生成され、初期選択されます。RenameWorksheetメソッドを使って必要に応じてシート名を変更するか、AddWorksheetメソッドを使ってシートを追加しましょう。
※尚、SpreadSheetLightにおける「シートの選択」とは、セルにアクセスする動作をSLDocumentオブジェクトに対して行った時、どのシートのセルを見るか?のセレクタです。SLDocumentオブジェクトのgsSelectedWorksheetNameプロパティに文字列として保持されており、SelectWorksheetメソッドで変更可能です。
C#
//シートの名前変更
var existingWorksheetName = "Sheet1";
var newWorksheetName = "新しいシート名";
slDocument.RenameWorksheet(existingWorksheetName, newWorksheetName);
//シートの追加
slDocument.AddWorksheet(newWorksheetName);
尚、AddWorksheetを読んだ段階で選択中のシートが新規追加したシートに切り替えられます。
セルの値の読み書き
セルにアクセスする場合もSLDocumentオブジェクトを使用します。現在選択中のシートにアクセスされます。
シートを変更する場合は、あらかじめSLDocument.SelectWorksheetメソッドを呼んでおきます。
C#
//シートの選択変更
var selectedSheetName = "Sheet1";
slDocument.SelectWorksheet(selectedSheetName);
セルに値を書き込むには、SetCellValueメソッドを使用します。
C#
//Sheet1シートのA2セルに書き込み
slDocument.SetCellValue(2, 1, "セルに入れる値");
//または
slDocument.SetCellValue("A2", "セルに入れる値");
セルの値を取得するには、GetCellValueAs系のメソッドを使用します。メソッドの使い分けによって取得する型を指定できます。汎用的に取得するのであれば、GetCellValueAsStringを使用すればよいでしょう。
C#
//Sheet1シートのA2セルに書き込み
string cellValue = slDocument.GetCellValueAsString(2, 1);
//または
string cellValue = slDocument.GetCellValueAsString("A2");
セルの書式設定
セルの書式指定はSLStyleクラスオブジェクトを使用します。次のコードが基本動作です。
C#
SLStyle slStyle = slDocument.CreateStyle();
//slStyleに対するいろいろな編集(後述)
//セルに反映
slDocument.SetCellStyle(rowNumber, columnNumber, slStyle);
以下、SLStyleクラスオブジェクトに対して書式を指定する方法を紹介します。
水平アライメント
C#
//左寄せ
slStyle.Alignment = new SLAlignment() { Horizontal = HorizontalAlignmentValues.Left };
//中央寄せ
slStyle.Alignment = new SLAlignment() { Horizontal = HorizontalAlignmentValues.Center };
//右寄せ
slStyle.Alignment = new SLAlignment() { Horizontal = HorizontalAlignmentValues.Right };
垂直アライメント
C#
//上寄せ
slStyle.Alignment = new SLAlignment() { Vertical = VerticalAlignmentValues.Top };
//中央寄せ
slStyle.Alignment = new SLAlignment() { Vertical = VerticalAlignmentValues.Center };
//下寄せ
slStyle.Alignment = new SLAlignment() { Vertical = VerticalAlignmentValues.Bottom };
セル内で折り返しして全体を表示
C#
slStyle.SetWrapText(true);
境界線の指定
それぞれ色・書式を指定しています。
C#
//上罫線
slStyle.Border.TopBorder.Color = System.Drawing.Color.Red;
slStyle.Border.TopBorder.BorderStyle = BorderStyleValues.Thin;
//下罫線
slStyle.Border.BottomBorder.Color = System.Drawing.Color.Red;
slStyle.Border.TopBorder.BorderStyle = BorderStyleValues.Thin;
//左罫線
slStyle.Border.LeftBorder.Color = System.Drawing.Color.Red;
slStyle.Border.LeftBorder.BorderStyle = BorderStyleValues.Thin;
//右罫線
slStyle.Border.RightBorder.Color = System.Drawing.Color.Red;
slStyle.Border.RightBorder.BorderStyle = BorderStyleValues.Thin;
セル内インデント
C#
slStyle.Alignment.Indent = 2;
印刷書式の指定
印刷書式は主にSLPageSettingsクラスオブジェクトを使用します。次のコードが基本動作です。
C#
SLPageSettings sLPageSettings = new SLPageSettings();
//いろいろな指定
//シートに反映
slDocument.SetPageSettings(sLPageSettings);
以下、SLPageSettingsオブジェクトに対する編集内容を紹介します。
縦横印刷ページ数を指定
C#
//幅1枚、縦2枚を指定
uint fitToWidth = 1;
uint fitToHeight = 2;
sLPageSettings.ScalePage(fitToWidth, fitToHeight);
紙サイズの指定
C#
//A4用紙に指定
sLPageSettings.PaperSize = SLPaperSizeValues.A4Paper;
紙の縦横の指定
C#
//水平(長編を横)で印刷
sLPageSettings.Orientation = OrientationValues.Landscape;
//垂直(長編を縦)で印刷
sLPageSettings.Orientation = OrientationValues.Portrait;
グラフの作成
SpreadSheetLightの強みと言えるグラフ記述機能を紹介します。SLChartクラスオブジェクトに対して編集を行います。
また、シートに反映するには、SlDocument.InsertChartメソッドのコールが必要なので注意しましょう。
SLChartオブジェクトの生成
オブジェクト生成時に、グラフデータの参照先を指定します。尚、系列・データ部を一括で範囲指定する必要があり、系列ラベルとデータ部が離れているグラフは現状対応していないと思われます。(調査中)
C#
//先に生成オプションを指定
SLCreateChartOptions sLCreateChartOptions = new() {
//行を系列として使用するか否か。
//行列を入れ替えたいときに便利です。
//Nullable<Boolean>形式のため、デフォルトでよい場合は指定する必要はありません。
RowsAsDataSeries = true
};
//位置の指定。セル番号でグラフデータの参照先を指定しています。
//系列とデータを両方含める必要があります。
int startRowIndex = 1;
int startColumnIndex = 1;
int endRowIndex = 3;
int endColumnIndex = 6
SLChart slChart = ws.CreateChart(startRowIndex, startColumnIndex, endRowIndex, endColumnIndex, sLCreateChartOptions);
//シートに反映 ※忘れないように!
slDocument.InsertChart(slChart);
グラフ種類の指定
C#
//棒グラフ
slChart.SetChartType(SLColumnChartType.ClusteredColumn);
//折れ線グラフ
slChart.SetChartType(SLColumnChartType.Line);
※ここで紹介する以外にも、SLColumnChartType列挙体に様々なグラフ種類が用意されています。
グラフエリアの位置・大きさ
C#
//上下左右の位置をセル番号で指定します。
double top = 3;
double left = 4;
double bottom = 10;
double right = 12;
slChart.SetChartPosition(top, left, bottom, right);
凡例の非表示
C#
slChart.HideChartLegend();
トラブルシューティング:例外「entries cannot be opened multiple times in update mode.」について
比較的新しい.NET環境でSpreadSheetLightを使用すると発生する現象のようです。参考:.net core - Error message "entries cannot be opened multiple times in update mode." in Spreadsheet Lite SaveAs function - Stack Overflow
発生する場合は、NuGetでの取得の際にSpreadsheetLight.Cross.Platformに入れ替えて試してみるといいでしょう。
記事筆者へのお問い合わせ、仕事のご依頼
当社では、IT活用をはじめ、業務効率化やM&A、管理会計など幅広い分野でコンサルティング事業・IT開発事業を行っております。
この記事をご覧になり、もし相談してみたい点などがあれば、ぜひ問い合わせフォームまでご連絡ください。
皆様のご投稿をお待ちしております。