delphi使用RichView控件 表格单元格合并

TRichView单元格合并

介绍

单元格合并

单元格合并是对表格单元格的操作。 多个单元格合并为一个(左上角)单元格。

在此操作之后,除了左上角的所有单元格都被销毁(并且相应的 Cells[r,c] 变为等于 nil)。

左上角的单元格增加了 ColSpanRowSpan 属性的值,并在视觉上跨越了合并的单元格。

即使合并后,表格的所有行也具有相同数量的单元格。

Rows.GetMainCell 方法可以获得与表格重叠的左上角单元格。

ColSpan Example

单元格跨越的行数和列数

单元格具有只读的 ColSpanRowSpan属性,类似于 HTML 中的 td colspan td rowspan,默认为 1。

如果 Cells[r,c].ColSpan>1,则该单元格向右跨越 (ColSpan-1) 个单元格:Cell[r,c], Cell[r,c+1], . .., Cell[r,c+Cell[r,c].ColSpan-1]。 在这种情况下,所有重叠的单元格 (Cell[r,c+1], ..., Cell[r,c+Cell[r,c].ColSpan-1]) 都被销毁并且等于 nil。 即使合并,该行中的单元格数仍然等于所有其他行中的单元格数。 RowSpan 也是如此:RowSpan>1 的单元格跨越下面的 (RowSpan-1) 单元格。

ColSpan and RowSpan example

属性

单元格跨越的行数TRVTableCellData.RowSpan

property RowSpan: Integer;

只读正整数值,指此单元格跨越的行数。

最初,对于所有单元格,此属性都等于 1。 由于单元格合并,可以更改此值。

此属性对应于 HTML 中的 td rowspan

单元格跨越的列数TRVTableCellData.ColSpan

property ColSpan: Integer;

只读正整数值,指此单元格跨越的列数。

最初,对于所有单元格,此属性都等于 1。 由于单元格合并,此值可以更改。

此属性对应于 HTML 中的 td colspan

方法

检查能否合并单元格TRVTableItemInfo.CanMergeCells

function CanMergeCells(TopRow, LeftCol, ColSpan, RowSpan: Integer;
  AllowMergeRC: Boolean): Boolean;

单元格合并的来源区域在 TopRowTopColColSpanRowSpan 中指定。

参数

TopRow 用于单元格合并的左上角单元格的行索引。

TopCol 用于单元格合并的左上角单元格的列索引。

ColSpan 合并的列数。

RowSpan 合并的行数。

AllowMergeRC 为True时,并且函数返回 False,进行合并后一个或多个行或列将只包含 nil。 不建议有这样的行或列,可以禁止此类操作或使用 DeleteEmptyRowsDeleteEmptyCols 删除它们(推荐后者)。

返回值 是否可以合并指定单元格。

如果将执行合并,生成的单元格是 Cells[TopRow, TopCol],其中 ColSpan=合并的列数 和 RowSpan=合并的行数。

合并可以完成条件

  1. Cells[TopRow, TopCol]<>nil
  2. 该区域形成了一块矩形形状(由于先前的单元格合并,没有单元格与其边界重叠)。 这一要求涵盖了第一个要求。
  3. Cells[TopRow, TopCol].ColSpan < ColSpanCells[TopRow, TopCol].RowSpan < RowSpan

检查能否合并选择的单元格TRVTableItemInfo.CanMergeSelectedCells

function CanMergeSelectedCells(AllowMergeRC: Boolean): Boolean;

CanMergeCells 相同,但单元格合并的来源区域是表中的选择。

参数

AllowMergeRC 为True时,并且函数返回 False,进行合并后一个或多个行或列将只包含 nil。 不建议有这样的行或列,可以禁止此类操作或使用 DeleteEmptyRowsDeleteEmptyCols 删除它们(推荐后者)。

返回值 是否可以合并所选单元格。

此方法可用于确定表格中的选择是否为矩形。

格式化的文档才能调用此方法。

合并单元格TRVTableItemInfo.MergeCells

procedure MergeCells(TopRow, LeftCol, ColSpan, RowSpan: Integer; AllowMergeRC: Boolean);

将指定的单元格合并为一个。

参数

TopRow 用于单元格合并的左上角单元格的行索引。

LeftCol 用于单元格合并的左上角单元格的列索引。

ColSpan 合并的列数。

RowSpan 合并的行数。

AllowMergeRC 为False时禁止执行合并,它会导致出现仅包含 nil 的行或列。 不建议有这样的行或列,可以禁止此类操作或使用 DeleteEmptyRowsDeleteEmptyCols删除它们(推荐后者)。

AllowMergeRC 参数只跟TRVTableItemInfo.CanMergeCells有关系

生成的单元格是 Cells[TopRow, TopCol],其中 ColSpan=合并的列数 和 RowSpan=合并的行数。

如果参数未形成矩形形状(因为先前的单元格合并),则此方法将失败(不执行任何操作)。 可以使用 CanMergeCells 检查合并的可能性。

合并选择的单元格TRVTableItemInfo.MergeSelectedCells

procedure MergeSelectedCells(AllowMergeRC: Boolean);

参数

AllowMergeRC 为False时禁止执行合并,它会导致出现仅包含 nil 的行或列。 不建议有这样的行或列,可以禁止此类操作或使用 DeleteEmptyRowsDeleteEmptyCols删除它们(推荐后者)。

如果选择没有形成矩形形状(因为先前的单元格合并),则此方法将失败(不执行任何操作)。 可以使用 CanMergeSelectedCells 检查合并的可能性。

格式化的文档才能调用此方法。

取消合并单元格TRVTableItemInfo.UnmergeCells

procedure UnmergeCells(TopRow, LeftCol, ColSpan, RowSpan: Integer; UnmergeRows, UnmergeCols: Boolean);

可以使用 MergeCellsMergeSelectedCells 方法合并单元格。

参数

TopRow 取消合并范围的左上角单元格的行索引。

LeftCol 取消合并范围的左上角单元格的列索引。

ColSpan 取消合并范围的列数。

RowSpan 取消合并范围的行数。

UnmergeRows 为True时,它将选择的单元格取消合并为 RowSpan 数量的行。

UnmergeCols 为True时,它将选择的单元格取消合并为 ColSpan 数量的列。

此方法取消合并从 Cells[TopRow, LeftCol]Cells[TopRow+RowSpan, LeftCol+ColSpan] 范围内的所有单元格。

UnmergeRowsUnmergeCells 可以都是True。

参数TopRow, LeftCol, ColSpan, RowSpan没有形成矩形形状,不会取消合并

取消合并选择的单元格TRVTableItemInfo.UnmergeSelectedCells

procedure UnmergeSelectedCells(UnmergeRows, UnmergeCols: Boolean);

可以使用 MergeCellsMergeSelectedCells 方法合并单元格。

参数

UnmergeRows 为True时,它将选择的单元格取消合并为 RowSpan 数量的行。

UnmergeCols 为True时,它将选择的单元格取消合并为 ColSpan 数量的列

UnmergeRowsUnmergeCells 可以都是True。

格式化的文档才能调用此方法。

水平拆分选择的单元格TRVTableItemInfo.SplitSelectedCellsHorizontally

将每个选定的单元格拆分为 RowCount 单元格(插入水平分隔符)。

procedure SplitSelectedCellsHorizontally(RowCount: Integer);

此方法拆分单元格,调用 UnmergeCellsInsertRowsMergeCells。 此方法可以更改行数。

建议仅在选择具有矩形时才能调用此方法,请参阅CanMergeSelectedCells

如果未选择任何单元格,则会拆分正在编辑的单元格。

格式化的文档才能调用此方法。

垂直拆分选择的单元格TRVTableItemInfo.SplitSelectedCellsVertically

procedure SplitSelectedCellsVertically(ColCount: Integer);

将每个选定的单元格拆分为 ColCount 单元格(插入垂直拆分器)。

此方法拆分单元格,调用 UnmergeCellsInsertColsMergeCells。 此方法可以更改列数。

建议仅在选择具有矩形时才能调用此方法,请参阅CanmergeSelectedCells

如果未选择任何单元格,则会拆分正在编辑的单元格。

格式化的文档才能调用此方法。

删除空行TRVTableItemInfo.DeleteEmptyRows

procedure DeleteEmptyRows;

删除所有只包含nil单元格的行。

nil单元格发生是由于单元格合并。

nil单元行发生在是出现在单元格合并或删除列之后。

此方法调用DeleteRows参数使用DecreaseHeight = False

全行选择多行进行合并时,除第一行外,其余行的所有单元格为nil,为空行

删除空列TRVTableItemInfo.DeleteEmptyCols

procedure DeleteEmptyCols;

删除所有只包含nil单元格的列。

nil单元格发生是由于单元格合并。

nil单元列发生在是出现在单元格合并或删除行之后。

此方法调用DeleteCols参数使用DecreaseWidth = False

全列选择多列进行合并时,除第一列外,其余列的所有单元格为nil,为空列

得到主(左上角)单元格TRVTableRows.GetMainCell

返回给定合并单元格的主(左上角)单元格。

function GetMainCell(ARow,ACol: Integer; out MRow, MCol: Integer): TRVTableCellData;

由于单元格合并,表中的某些单元格可能等于 nil。 此方法允许找到与给定合并单元格重叠的左上角单元格。

参数

ARrowACol 指定表格中的某些单元格。 Table.Cells[ARrow, ACol] 可以为nil

MRowMCol 输出主单元格的位置。 这个单元格永远不等于nil

如果 Table.Cells[ARow, ACol]<>nil 那么 MRow 将等于 ARow 并且 MCol 将等于 ACol

返回值 Table.Cells[MRow, MCol]

例子

合并单元格

uses RVTable, RVItem;

procedure TForm1.Button1Click(Sender: TObject);
var
  Table: TRVTableItemInfo;
  Row, Col: Integer;
begin
  //创建5行4列的表格
  Table := TRVTableItemInfo.CreateEx(5, 4, RichViewEdit1.RVData);

  //设置表格边框和背景色
  Table.Color := clNone;
  Table.BorderStyle := rvtbColor;
  Table.CellBorderStyle := rvtbColor;
  Table.BorderWidth := 1;
  Table.CellBorderWidth := 1;

  //添加表格数据
  for Row := 0 to Table.RowCount - 1 do
    for Col := 0 to Table.ColCount - 1 do
    begin
      Table.Cells[Row, Col].BestWidth := 60;
      Table.Cells[Row, Col].BestHeight := 20;
      Table.Cells[Row, Col].Color := clCream;
      Table.Cells[Row, Col].Clear;
      Table.Cells[Row, Col].AddFmt('%d,%d', [Row, Col], 0, 0);
    end;

  //合并单元格(从第1行第2列开始,合并2列3行)
  Table.MergeCells(0, 1, 2, 3, True);
  //合并后单元格包括[0,1][0,2][1,1][1,2][2,1][2,2]
  Table.Cells[0, 1].Clear;
  Table.Cells[0, 1].AddNL('单元格索引[0,1]', 0, 0);
  Table.Cells[0, 1].AddFmt('RowSpan = %d', [Table.Cells[0, 1].RowSpan], 0, 0);
  Table.Cells[0, 1].AddFmt('ColSpan = %d', [Table.Cells[0, 1].ColSpan], 0, 0);
  //将表格添加到文档中
  RichViewEdit1.InsertItem('', Table);
end;

取消合并单元格

uses RVTable, RVItem;

procedure TForm1.Button2Click(Sender: TObject);
var
  Item: TCustomRVItemInfo;
  Table: TRVTableItemInfo;
  Data: Integer;
  Rve: TCustomRichViewEdit;
  ItemNo: Integer;
begin
  //获取当前选择的表格
  if not RichViewEdit1.CanChange or
    not RichViewEdit1.GetCurrentItemEx(TRVTableItemInfo, Rve, Item) then
    Exit;
  Table := TRVTableItemInfo(Item);
  ItemNo := Rve.GetItemNo(Table);
  Rve.BeginItemModify(ItemNo, Data);

  //取消范围内单元格的列和行
  //传入参数TopRow, LeftCol, ColSpan, RowSpan没有形成矩形形状,不会取消合并
  //Cells[TopRow, LeftCol] = nil不会取消合并
  //取消Cells[TopRow, LeftCol]到Cells[TopRow+RowSpan, LeftCol+ColSpan]范围内的所有单元格
  Table.UnmergeCells(0, 1, 1, 1, True, True);
  //取消范围[0,1]到[1,2]内所有合并的单元格
  Table.Cells[0, 1].Clear;
  Table.Cells[0, 1].AddNL('[0,1]', 0, 0);
  Table.Cells[1, 2].Clear;
  Table.Cells[1, 2].AddNL('[1, 2]', 0, 0);
  Rve.EndItemModify(ItemNo, Data);
  Rve.Change;
end;

删除空行

uses RVTable, RVItem;

procedure TForm1.Button3Click(Sender: TObject);
var
  Item: TCustomRVItemInfo;
  Table: TRVTableItemInfo;
  Data: Integer;
  Rve: TCustomRichViewEdit;
  ItemNo: Integer;
  Rows: Integer;
begin
  //获取当前选择的表格
  if not RichViewEdit1.CanChange or
    not RichViewEdit1.GetCurrentItemEx(TRVTableItemInfo, Rve, Item) then
    Exit;
  Table := TRVTableItemInfo(Item);
  ItemNo := Rve.GetItemNo(Table);
  Rve.BeginItemModify(ItemNo, Data);

  //合并多行为1行(第4行和第5行合并为1行)时,除合并开始行外,其他行为空行(单元格全为nil)
  //参数AllowMergeRC = False时,如果合并产生空行,将不执行合并
  //Table.MergeCells(3, 0, Table.ColCount, 2, False);
  Table.MergeCells(3, 0, Table.ColCount, 2, True);
  //合并后行数不产生变化
  Rows := Table.RowCount;
  //删除产生的空行
  Table.DeleteEmptyRows;
  //删除空行后,行数发生变化
  Table.Cells[3, 0].Clear;
  Table.Cells[3, 0].AddFmt('合并后行数%d 删除空行后行数%d', [Rows, Table.RowCount], 0, 0);

  Rve.EndItemModify(ItemNo, Data);
  Rve.Change;
end;

获取合并单元格信息

uses RVTable, RVItem;

procedure TForm1.Button4Click(Sender: TObject);
var
  Item: TCustomRVItemInfo;
  Table: TRVTableItemInfo;
  Data: Integer;
  Rve: TCustomRichViewEdit;
  ItemNo: Integer;
  Row, Col: Integer;
  MRow, MCol: Integer;
begin
  //获取当前选择的表格
  if not RichViewEdit1.CanChange or
    not RichViewEdit1.GetCurrentItemEx(TRVTableItemInfo, Rve, Item) then
    Exit;
  Table := TRVTableItemInfo(Item);
  ItemNo := Rve.GetItemNo(Table);
  Rve.BeginItemModify(ItemNo, Data);

  //遍历所有单元格
  //Table.RowCount = Table.Rows.Count
  //Table.ColCount = Table.Rows[Row].Count
  for Row := 0 to Table.Rows.Count - 1 do
    for Col := 0 to Table.Rows[Row].Count - 1 do
    begin
      //Cells[Row, Col] <> nil或Rows.GetMainCell 都可以得到主(左上角)单元格坐标
      //Cells[Row, Col] <> nil方式得到主(左上角)单元格坐标(Cells[Row, Col] = nil 与左上角的单元格重叠,不能操作)
      if Table.Cells[Row, Col] <> nil then
      begin
        if (Table.Cells[Row, Col].RowSpan > 1) or (Table.Cells[Row, Col].ColSpan > 1) then
        begin
          Table.Cells[Row, Col].Clear;
          Table.Cells[Row, Col].AddFmt('主单元格[%d,%d]', [Row, Col], 0, 0);
        end;
      end;
      //Rows.GetMainCell方式得到主(左上角)单元格坐标
      Table.Rows.GetMainCell(Row, Col, MRow, MCol);
      if (Row <> MRow) or (Col <> MCol) then
      begin
        Table.Cells[MRow, MCol].Clear;
        Table.Cells[MRow, MCol].AddFmt('主单元格[%d,%d]', [Row, Col], 0, 0);
      end;
    end;

  Rve.EndItemModify(ItemNo, Data);
  Rve.Change;
end;
posted @ 2021-10-27 09:43  txgh  阅读(310)  评论(0编辑  收藏  举报