• delphi使用RichView控件 表格保存和复制


    TRichView表格保存和复制

    介绍

    很少直接调用 TRVTableItemInfo.SaveToStream 。通常将表格保存到 RVF 文件或带有主文档的流中,通过TCustomRichView.SaveRVFToStream方法。

    很少直接调用 TRVTableItemInfo.LoadFromStream 。 通常表格是从 RVF 文件或带有主文档的流中加载的,通过TCustomRichView.LoadRVFFromStream方法。

    使用TRVTableItemInfo.SaveToStream实现复制表,使用TRVTableItemInfo.SaveRowsToStream实现复制行。

    方法

    表保存到Stream中TRVTableItemInfo.SaveToStream

    procedure SaveToStream(Stream: TStream);
    

    将表保存到 Stream 中。

    表的行保存到Stream中TRVTableItemInfo.SaveRowsToStream

    将表的指定行索引(从 IndexIndex+Count-1)保存到 Stream 中。

    procedure SaveRowsToStream(Stream: TStream; Index, Count: Integer);
    

    输出的StreamSaveToStream 兼容。

    即使由于单元格合并 RowSpan>1 ,存在与IndexIndex+Count-1 这些行重叠的单元格,结果也将是正确的。

    从Stream加载表TRVTableItemInfo.LoadFromStream

    procedure LoadFromStream(Stream: TStream);
    

    Stream 中加载表。

    必须使用 SaveToStreamSaveRowsToStream 方法保存表。 只有 TRVStyle 中的文本、段落和列表样式集合与保存时相同,才能正确加载表格。

    例子

    复制表格

    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;
    
      //合并单元格(从第3行第2列开始,合并2行)
      Table.MergeCells(2, 1, 1, 2, True);
    
      //将表格添加到文档中
      RichViewEdit1.InsertItem('', Table);
    end;
    
    procedure TForm1.Button2Click(Sender: TObject);
    var
      Item: TCustomRVItemInfo;
      Table, NewTable: TRVTableItemInfo;
      Rve: TCustomRichViewEdit;
      Stream: TMemoryStream;
    begin
      //获取当前选择的表格
      if not RichViewEdit1.CanChange or
        not RichViewEdit1.GetCurrentItemEx(TRVTableItemInfo, Rve, Item) then
        Exit;
      Table := TRVTableItemInfo(Item);
    
      Stream := TMemoryStream.Create;
      try
        //从第3行开始,复制3行表格(复制开始行中包含合并nil的单元格,会将nil主单元格的内容复制)
        Table.SaveRowsToStream(Stream, 2, 3);
        Stream.Position := 0;
        //创建新表格(加载数据会将原先表格中的内容都清除,创建表格时行和列不起作用)
        NewTable := TRVTableItemInfo.CreateEx(3, 3, Rve.RVData);
        //加载复制数据
        NewTable.LoadFromStream(Stream);
        //添加分页符
        Rve.InsertPageBreak;
        //将表格添加到文档中
        Rve.InsertItem('', NewTable);
      finally
        Stream.Free;
      end;
    end;
    

    分表函数

    function SplitTable(rve: TCustomRichViewEdit; table: TRVTableItemInfo;
      RowCountInFirstTable: Integer; PageBreak: Boolean): Boolean;
    var r, c, mr, mc: Integer;
        newtable: TRVTableItemInfo;
        Stream: TMemoryStream;
    begin
      Result := False;
      if RowCountInFirstTable>=table.RowCount then
        exit;
      for c := 0 to table.ColCount-1 do
        if table.Cells[RowCountInFirstTable, c] = nil then begin
          table.Rows.GetMainCell(RowCountInFirstTable, c, mr, mc);
          if mr<RowCountInFirstTable then
            exit;
        end;
      Stream := TMemoryStream.Create;
      table.SaveRowsToStream(Stream, RowCountInFirstTable,
        table.RowCount-RowCountInFirstTable);
      Stream.Position := 0;
      newtable := TRVTableItemInfo.CreateEx(0, 0, rve.RVData);
      newtable.LoadFromStream(Stream);
      if PageBreak then
        newtable.PageBreakBefore := True;
      Stream.Free;
      rve.BeginUndoGroup(rvutModifyItem);
      rve.SetUndoGroupMode(True);
      try
        table.DeleteRows(RowCountInFirstTable, table.RowCount-RowCountInFirstTable, True);
        // table.GetItem 与.GetItem(table) 相同,但速度更快
        rve.SetSelectionBounds(table.GetMyItemNo, 1, table.GetMyItemNo, 1);
        rve.InsertItem('', newtable);
      finally
        rve.SetUndoGroupMode(False);
      end;
      Result := True;
    end;
    
    

    将表分为两个表。

    参数

    rve 包含table的编辑器。

    table 要划分的表。

    RowCountInFirstTable 第一个表具有的行数。第一个表具有的行数 = RowCountInFirstTable, 第二个表具有的行数 = table.RowCount-RowCountInFirstTable.

    PageBreak 如果为 True,将在表之间插入分页符。

    返回值 True 表被划分。

    rvetable可以通过RichViewEdit1.GetCurrentItemEx获取。

    这是一个编辑操作,用户可以撤销和重做。

  • 相关阅读:
    CopyOnWriteArrayList 读写分离,弱一致性
    Java中定时器Timer致命缺点(附学习方法)
    排队打饭:公平锁和非公平锁(面试)
    母鸡下蛋实例:多线程通信生产者和消费者wait/notify和condition/await/signal条件队列
    volatile,synchronized可见性,有序性,原子性代码证明(基础硬核)
    Synchronized用法原理和锁优化升级过程(面试)
    Java中多线程安全问题实例分析
    iOS 相互引用引起内存泄露问题说明
    iOS app 集成友盟推送问题
    ios即时通讯客户端开发之-mac上基于XMPP的聊天客户端开发环境搭建
  • 原文地址:https://www.cnblogs.com/txgh/p/15547759.html
Copyright © 2020-2023  润新知