Excel のテーブル(ListObject)は書式ではなくオブジェクトです。
V5 もそう扱います。TableDefinition が持つのは範囲・見出し行数・スタイル名だけで、
各セルの色は「そのセルが範囲のどこに居るか」から描画のたびに解かれます。
色をセルに焼き込まないので、
- 10 万行のテーブルでもオブジェクトは 1 個、
- 途中に行を挿しても縞が崩れず、
- 手で塗ったセルは縞を破れ、
- xlsx には ad-hoc な塗りではなく本物の
xl/tables/tableN.xmlとして出ます。
基本
using unvell.ReoGrid.Core;
using unvell.ReoGrid.Core.Tables;
// 先頭行を見出しにして A1:D100 をテーブルにする。既定は TableStyleMedium2
var table = ws.AddTable("A1:D100");
// 列名は見出し行から採られる
string first = table.Columns[0].Name;
// テーブルをやめる(Excel の「範囲に変換」)。書式はセルに入っていないので消えるだけ
ws.RemoveTable(table.Name);
_ = first;
AddTable は範囲を A1 形式のアドレスか名前付き範囲、あるいは RangePosition で受け取ります。
先頭行が見出しになり、列名はその行のテキストから採られます(空白や重複は
Column3 / Qty2 のように一意化されます — Excel が列名の衝突を許さないため)。
スタイルとオプション
// スタイルとオプションを指定して作る
var table = ws.AddTable(RangePosition.Parse("A1:D100"), new AddTableOptions
{
Name = "Sales",
Style = "TableStyleMedium7", // 組込 60 種。名前はファイルにそのまま残る
ShowRowStripes = true, // 交互行(既定 true)
ShowFirstColumn = true, // 先頭列を強調
ShowFilterButton = true, // 見出し行にフィルタ▽を出す(既定 false)
});
// 後から切り替える。Style は record struct なので with で書き換える
table.Style = table.Style with { ShowColumnStripes = true, ShowRowStripes = false };
| オプション | 既定 | 内容 |
|---|---|---|
Name | Table1, Table2, … | ブック内で一意な内部名。識別子なので英字か _ で始まり、英数字・.・_ のみ(空白不可、Q1 のようなセル参照も不可)— Excel は構造化参照でこの名前を綴るため |
Style | TableStyleMedium2 | 組込スタイル名。未知の名前でも書き換えません(後述) |
HeaderRowCount | 1 | 0 か 1。Excel のテーブルに複数見出し行はありません |
TotalsRowCount | 0 | 0 か 1。配色はしますが集計関数は未実装です(往復はします) |
ShowRowStripes | true | 交互行(しま模様) |
ShowColumnStripes | false | 交互列 |
ShowFirstColumn / ShowLastColumn | false | 先頭列・末尾列の強調 |
ShowFilterButton | false | 見出し行にフィルタ▽を出す(シートの auto-filter を張ります。範囲は見出しとデータ行で、集計行は含みません — Excel と同じく、何を絞り込んでも集計行は残ります) |
ShowFilterButton が既定で false なのは、シートが持てる auto-filter が 1 つだけだからです。
既定で true にすると、2 つ目のテーブルを作った瞬間に 1 つ目から▽が消えます。

図は既定の TableStyleMedium2 に ShowFilterButton と TotalsRowCount = 1 を付けたものです。
集計行の数式(ここでは SUBTOTAL(109,B2:B8))は V5 が書くのではなく、アプリ側で入れています(後述)。
交互行(しま模様)
縞は Excel と同じく先頭のデータ行から付きます(1 行目・3 行目・5 行目…が縞の色)。 数え方はシート単位の縞と同じで、可視行だけを数えるので、 フィルタで行が消えても縞が 2 行続きません。 テーブルの中ではテーブルの縞が優先され、シートの縞はテーブルの縁で止まります。
Excel は縞をテーブルスタイルの中に持っているので、 xlsx を往復するのはこちらの縞です(シート単位の縞は Excel に置き場所が無く、reogrid-json のみ)。
塗りの優先順位
強い順に:
- 条件付き書式
- セル自身の書式(セル → 行 → 列のスタイル鎖)
- テーブルスタイル
- シートの縞(テーブルの外だけ)
テーブルは継承鎖の Root ◁ Table ◁ Column ◁ Row ◁ Cell に入ります。
セル自身より弱いので、1 行だけ黄色く塗ればそこだけ縞を破れます。
罫線も同じで、テーブルの枠線の上に手書きの罫線が辺ごとに乗ります。
テーブルの内側では、スタイルの各部分が Excel と同じ順に重なります(後ろほど強い): テーブル全体 → 列の縞 → 行の縞 → 末尾列 → 先頭列 → 見出し行 → 集計行。 各部分は自分が指定した項目だけを上書きするので、塗りを持たない見出し行 (Medium 22–28 など)にはテーブル全体の塗りがそのまま見えます。
問い合わせ
bool any = ws.HasTables;
// そのセルを覆っているテーブル(無ければ null)
TableDefinition? at = ws.GetTableAt(5, 2);
// 名前で引く(大小無視)
TableDefinition? byName = ws.GetTable("Sales");
// 見出し・集計行を除いたデータ部分
RangePosition data = at?.DataRange ?? default;
// そのセルにテーブルが与えている塗り(セル自身の書式より弱い層)
var contributed = ws.GetTableStyle(5, 2);
// 手書きの罫線をテーブルの罫線の上に重ねた結果
CellBorders borders = ws.GetEffectiveBorders(5, 2);
_ = (any, byName, data, contributed, borders);
組込スタイルと自前の配色
Excel はファイルにスタイル名しか書きません。TableStyleMedium7 がどう見えるかは
アプリ側の知識です。その中身は公開されていて、ECMA-376 が組込 60 種を
presetTableStyles.xml として定義しています。V5 はこの定義をそのまま持っているので、
どの行に縞を付け、どの辺に罫線を引き、どの文字を太くするかが Excel と一致します。

組込スタイルは名前ほど規則的ではありません。Light だけでも、上下の罫線と濃い文字色(1–7)、
塗った見出しと縞ごとの罫線(8–14)、格子(15–21)と形が 3 通りあり、Dark 9–11 の見出しは
自分のアクセントとは別の色を使います。色は Office の既定テーマ(2013 以降)から
OOXML と同じ HSL の tint 曲線で解くので、Office のスウォッチとの差は RGB で 1〜2 程度です
(Medium 2 の縞は Office の #D9E1F2 に対して #DAE3F3)。
知らない名前は既定の配色で描きますが、名前は書き換えません。
ただし残るのは名前だけです。V5 はユーザー定義スタイルの定義(Excel が styles.xml の
<tableStyles> に書くもの)を読み書きしないので、Excel で作ったユーザー定義スタイルは V5 で
保存し直すと定義が失われ、Excel ではスタイル無しのテーブルとして表示されます。
下の TableStyles.Register で登録した配色も同じで、ファイルには名前しか残らず、
Excel では書式の無いテーブルになります。Excel で開くファイルには組込 60 種を使ってください。
// 組込スタイルの一覧(Light 1–21 / Medium 1–28 / Dark 1–11)
foreach (string name in TableStyles.BuiltinNames())
{
TableStyleDefinition def = TableStyles.Resolve(name);
_ = (def.HeaderFill, def.RowStripeFill, def.WholeBorderColor);
}
// 自前の配色を登録する(同名の組込を上書きもできる)
TableStyles.Register(new TableStyleDefinition
{
Name = "BrandTable",
HeaderFill = 0xFF1F3864,
HeaderColor = 0xFFFFFFFF,
HeaderBold = true,
RowStripeFill = 0xFFEAF0F8,
WholeBorderColor = 0xFF1F3864,
});
HeaderFill や RowStripeFill は簡易記法で、実体は Excel の tableStyleElement に当たる
TableStyleElement(WholeTable / HeaderRow / TotalRow / FirstColumn / LastColumn /
FirstRowStripe / SecondRowStripe / FirstColumnStripe / SecondColumnStripe)です。
各要素は塗り・文字色・太字と、外周 4 辺と内側の罫線(Horizontal / Vertical)を持ちます。
// 罫線の太さや行間の罫線まで決めるなら、Excel の tableStyleElement と同じ単位で書く
TableStyles.Register(new TableStyleDefinition
{
Name = "BrandLedger",
WholeTable = new TableStyleElement
{
Horizontal = new BorderEdge(BorderLineStyle.Solid, 0xFFB4C6E7, 1), // 行と行の間
Bottom = new BorderEdge(BorderLineStyle.Solid, 0xFF1F3864, 2), // 表の下端
},
HeaderRow = new TableStyleElement { Fill = 0xFF1F3864, Color = 0xFFFFFFFF, Bold = true },
FirstRowStripe = new TableStyleElement { Fill = 0xFFEAF0F8 }, // 先頭のデータ行から
TotalRow = new TableStyleElement
{
Bold = true,
Top = new BorderEdge(BorderLineStyle.Double, 0xFF1F3864, 3),
},
});
行・列の挿入と削除
テーブルは自分が説明しているデータに追従します。 上に行を挿せば下がり、途中に挿せば伸び、列を消せば列リストからもその列が抜けます。 テーブルの行が全部消えれば、テーブルも一緒に消えます。
入出力
| 形式 | 内容 |
|---|---|
| reogrid-json | tables(reogrid-web の JsonTableDefinition と同形) |
| XLSX | xl/tables/tableN.xml + [Content_Types].xml の Override + シートの _rels + <tableParts>。番号はブック全体の通し番号 |
どちらの形式でも、テーブルの色はセルに書きません。Excel ではセル自身の書式がテーブルスタイルより 強いので、セルに書き込むと並べ替えで縞が行ごと動き、スタイルを変えても色が変わらなくなります。
XLSX では、Excel が開けるファイルにするために次の 3 点を守っています。どれか 1 つでも外れると、 Excel は修復も含めてファイルを開けません(デスクトップ版 Excel で確認)。
- テーブルのフィルタ(
ShowFilterButton)はテーブルのパーツ側に書き、シートの<autoFilter>には書かない。 テーブルと重なるシートのフィルタがあると開けません。読み込み時はテーブル側のフィルタをシートのフィルタとして 戻します(シートが自分のフィルタを持っていない場合) - フィルタの範囲は集計行を含まない
- 集計行の各セルの中身を列に宣言する。文字は
totalsRowLabel、数式や値はtotalsRowFunction="custom"+<totalsRowFormula>(セル自身の数式もそのまま書きます)
まだ無いもの
- 集計行の集計関数(
SUBTOTAL)— 行の配色と往復だけ - 構造化参照(
=Table1[列名]) - 隣のセルを編集したときの自動拡張
- ユーザー定義テーブルスタイルの定義(styles.xml の
<tableStyles>)の読み書き