} // Constructor /// <summary> /// マージされたセルのサイズをチェック(セルの表示/非表示を考慮する) /// </summary> /// <param name="range"> /// マージされた領域 /// </param> /// <param name="hidden"> /// Excel上で非表示のセルをTableでも非表示にするか /// </param> /// <returns> /// マージされたセルのサイズ /// </returns> private CellSize CheckCellSize(Excel.Range range, bool hidden = false) { CellSize cellsize = new CellSize() { col = 0, row = 0 }; // 列方向のインデックス作成 for (int i = 1; i <= range.Rows.Count; i++) { Excel.Range line = range.Rows[i]; // 表示/非表示考慮する設定でかつ非表示だったら if (hidden & line.Hidden) { continue; } cellsize.row++; } // 行方向のインデックス作成 for (int i = 1; i <= range.Columns.Count; i++) { Excel.Range line = range.Columns[i]; // 表示/非表示考慮する設定でかつ非表示だったら if (hidden & line.Hidden) { continue; } cellsize.col++; } return(cellsize); } // CheckCellSize
/// <summary> /// セルサイズに応じて結合結果をLaTexの表現で返す。 /// </summary> /// <param name="size"> /// 結合セルサイズ /// </param> /// <param name="content"> /// 結合セルの文字列 /// </param> /// <param name="lvrule"> /// 対象セルの左の鉛直罫線 /// </param> /// <param name="align"> /// 対象セルの文字寄せ /// </param> /// <param name="rvrule"> /// 対象セルの右の鉛直罫線 /// </param> /// <param name="lvrule_top"> /// 対象セル行のフォーマットとなる左の鉛直罫線 /// </param> /// <param name="align_top"> /// 対象セル行のフォーマットとなる文字寄せ情報 /// </param> /// <param name="rvrule_top"> /// 対象セル行のフォーマットとなる右の鉛直罫線 /// </param> /// <returns> /// 結合セルの結合結果 /// </returns> private string multicell( CellSize size, string content, LineType lvrule, Align align, LineType rvrule, LineType lvrule_top, Align align_top, LineType rvrule_top) { string lvrule_str = linetype_to_vrule(lvrule); string rvrule_str = linetype_to_vrule(rvrule); string align_str = align_to_str(align); // 行と列の双方向結合 if (size.col > 1 & size.row > 1) { return(multicolumn(size.col, lvrule_str, align_str, rvrule_str, multirow(size.row, content))); } // 列(↓)方向のみの結合 else if (size.row > 1) { // セルのフォーマットがデフォルトと異なる -> multicolumnで囲む if (lvrule_top != lvrule | align_top != align | rvrule_top != rvrule) { return(multicolumn(size.col, lvrule_str, align_str, rvrule_str, multirow(size.row, content))); } // セルのフォーマットがデフォルトと同じ else { return(multirow(size.row, content)); } } // 行(→)方向のみの結合 else if (size.col > 1) { return(multicolumn(size.col, lvrule_str, align_str, rvrule_str, content)); } // 結合は無し else { // セルのフォーマットがデフォルトと異なる -> multicolumnで囲む if (lvrule_top != lvrule | align_top != align | rvrule_top != rvrule) { return(multicolumn(size.col, lvrule_str, align_str, rvrule_str, content)); } // セルのフォーマットがデフォルトと同じ else { return(content); } } } // multicell
/// <summary> /// コンストラクタ /// </summary> /// <param name="range"> /// 整理するExcelのRange /// </param> /// <param name="hidden"> /// Excel上で非表示のセルをTableでも非表示にするか /// </param> public RangeConvert(Excel.Range range, bool hidden = false) { List <int> row_index = new List <int>(); List <int> col_index = new List <int>(); // 列方向のインデックス作成 for (int i = 1; i <= range.Rows.Count; i++) { Excel.Range line = range.Rows[i]; // 表示/非表示考慮する設定でかつ非表示だったら if (hidden & line.Hidden) { continue; } row_index.Add(i); } // 行方向のインデックス作成 for (int i = 1; i <= range.Columns.Count; i++) { Excel.Range line = range.Columns[i]; // 表示/非表示考慮する設定でかつ非表示だったら if (hidden & line.Hidden) { continue; } col_index.Add(i); } // 初期化 // Rownum, Colnum rownum = row_index.Count; colnum = col_index.Count; // Contents contents = new string[rownum, colnum]; // Horizontal Rule Map hrule_map = new LineType[rownum + 1, colnum]; // Vertical Rule Map vrule_map = new LineType[rownum, colnum + 1]; // Align Map [rownum, colnum] align_map = new Align[rownum, colnum]; // MergeMap [rownum, colnum] merge_map = new MergeType[rownum, colnum]; // Cell Size Map [rownum, colnum] cellsize_map = new CellSize[rownum, colnum]; // セルの文字寄せ,コンテンツ,マージ情報,マージサイズの取得 for (int i = 0; i < row_index.Count; i++) { for (int j = 0; j < col_index.Count; j++) { Excel.Range targetcell = range[row_index[i], col_index[j]]; // Align Map align_map[i, j] = CellAlign(targetcell); // マージの有無を確認 if (targetcell.MergeCells) { MergeType cell_mergeType = CheckMergeType(targetcell.MergeArea, targetcell, hidden); // TopLeftだったら if (cell_mergeType == MergeType.lefttop) { cellsize_map[i, j] = CheckCellSize(targetcell.MergeArea, hidden); if (cellsize_map[i, j].col == 1 & cellsize_map[i, j].row == 1) { // TopLeftでもセルサイズが[1,1]だったらマージされてないと考える merge_map[i, j] = MergeType.notmerged; } else { merge_map[i, j] = MergeType.lefttop; } contents[i, j] = targetcell.MergeArea[1, 1].Text; } // Topだったら else if (cell_mergeType == MergeType.top) { cellsize_map[i, j] = new CellSize() { row = 1, col = 1 }; merge_map[i, j] = MergeType.top; contents[i, j] = ""; } // Top以外だったら else { cellsize_map[i, j] = new CellSize() { row = 1, col = 1 }; merge_map[i, j] = MergeType.nottop; contents[i, j] = ""; } } else { cellsize_map[i, j] = new CellSize() { row = 1, col = 1 }; merge_map[i, j] = MergeType.notmerged; contents[i, j] = targetcell.Text; } } // Column Loop } // Row Loop // 罫線情報の取得 // 一番上の水平方向罫線の確認 for (int j = 0; j < col_index.Count; j++) { hrule_map[0, j] = CheckLineType(range[row_index[0], col_index[j]], Excel.XlBordersIndex.xlEdgeTop); } // 左端の鉛直方向の罫線の確認 for (int i = 0; i < row_index.Count; i++) { vrule_map[i, 0] = CheckLineType(range[row_index[i], col_index[0]], Excel.XlBordersIndex.xlEdgeLeft); } // 表の中身と右端と下の罫線の確認 for (int i = 0; i < row_index.Count; i++) { for (int j = 0; j < col_index.Count; j++) { // 簡単のために対象のセルを一旦変数に格納 Excel.Range targetcell = range[row_index[i], col_index[j]]; // 水平方向罫線 // Horizontal Rule Map -> 下側の罫線の確認 // このセルの下にもまだセルがある(一番下の列ではない) if (i + 1 != row_index.Count) { // マージされていて、このセルの下のセルは先頭列ではない。 if (merge_map[i, j] != MergeType.notmerged & merge_map[i + 1, j] == MergeType.nottop) { hrule_map[i + 1, j] = LineType.noline; } else { hrule_map[i + 1, j] = CheckLineType(targetcell, Excel.XlBordersIndex.xlEdgeBottom); } } else { hrule_map[i + 1, j] = CheckLineType(targetcell, Excel.XlBordersIndex.xlEdgeBottom); } // 鉛直方向罫線 // Vertical Rule Map -> 右側の罫線の確認 vrule_map[i, j + 1] = CheckLineType(targetcell, Excel.XlBordersIndex.xlEdgeRight); } // Column Loop } // Row Loop } // Constructor
public Tabular(RangeConvert tb_dataset) { // 初期化 colnum = tb_dataset.colnum; rownum = tb_dataset.rownum; // 内部のコンテンツリスト contents = new List <string> [rownum]; for (int i = 0; i < tb_dataset.rownum; i++) { contents[i] = new List <string>(); } // 列の水平罫線リスト hrule_lines = new string[rownum]; LineType[] hrule_linetypes = new LineType[colnum]; // 表の上の罫線をチェック for (int j = 0; j < colnum; j++) { hrule_linetypes[j] = tb_dataset.hrule_map[0, j]; } hrule_top = hrule_str(hrule_linetypes); // フォーマットの作成 LineType[] vrule_linetypes = new LineType[colnum + 1]; Align[] valign_types = new Align[colnum]; vrule_linetypes[0] = tb_dataset.vrule_map[0, 0]; for (int j = 0; j < colnum; j++) { vrule_linetypes[j + 1] = tb_dataset.vrule_map[0, j + 1]; valign_types[j] = tb_dataset.align_map[0, j]; } format = tabular_format(vrule_linetypes, valign_types); // 中身のコンテンツ行を作成 for (int i = 0; i < rownum; i++) { for (int j = 0; j < colnum; j++) { // セルの水平方向罫線を生成するための配列を作る。 hrule_linetypes[j] = tb_dataset.hrule_map[i + 1, j]; // フォーマット CellSize cell_size = tb_dataset.cellsize_map[i, j]; // 先頭列の文字装飾 LineType lvrule_top = tb_dataset.vrule_map[0, j]; // left vrule LineType rvrule_top = tb_dataset.vrule_map[0, j + cell_size.col]; // right vrule +1をmulticol分増やす? Align cell_align_top = tb_dataset.align_map[0, j]; // 文字装飾 LineType lvrule = tb_dataset.vrule_map[i, j]; // left vrule LineType rvrule = tb_dataset.vrule_map[i, j + cell_size.col]; // right vrule +1をmulticol分増やす? Align cell_align = tb_dataset.align_map[i, j]; MergeType cell_mergeType = tb_dataset.merge_map[i, j]; // コンテンツ string cell_content = tb_dataset.contents[i, j]; // マージセルの左上 if (cell_mergeType == MergeType.lefttop) { contents[i].Add(multicell(cell_size, cell_content, lvrule, cell_align, rvrule, lvrule_top, cell_align_top, rvrule_top)); } // マージセルの一番上の行 -> 一番左以外はまとめられるのでスキップ else if (cell_mergeType == MergeType.top) { continue; } // マージセルの一番上以外の行 else if (cell_mergeType == MergeType.nottop) { // 基本結合されるので空白の行だが、罫線はmulticolumnなどで反映する必要がある場合もある。 contents[i].Add(multicell(cell_size, "", lvrule, cell_align, rvrule, lvrule_top, cell_align_top, rvrule_top)); } // 結合セルではない。 else { contents[i].Add(multicell(cell_size, cell_content, lvrule, cell_align, rvrule, lvrule_top, cell_align_top, rvrule_top)); } } // セルの下水平方向罫線を出力 hrule_lines[i] = hrule_str(hrule_linetypes); } }