11 августа 2021

Использование нескольких шрифтов и цветов в одной ячейке MS Excel одновременно

    Каждое слово или буква в ячейке MS Excel может иметь свой шрифт, стиль шрифта, цвет и размер. Это позволяет сделать таблицу более наглядной и удобочитаемой. Для подобного форматирования ячейки достаточно перевести ее в режим редактирования нажатием клавиши F2 или двойным кликом левой кнопки мыши, выделить нужный участок текста и поменять параметры его шрифта. Как это сделать программным способом?
    Для начала посмотрим, как раскрасить ячейку в программе, которая работает с файлами MS Excel через его OLE-сервер. В этом нам поможет свойство ячейки Characters(start, length), которое позволяет манипулировать последовательностью символов в тексте ячейки (где start – номер начального символа, а length – количество символов для обработки).
uses
  System.SysUtils, System.UITypes,
  System.Variants, System.Win.ComObj, Winapi.Windows, Winapi.ActiveX;

procedure UseOLE;
var
  ovEA  : OleVariant;
  ovCell: OleVariant;
  ovFont: OleVariant;
begin
  ovEA := CreateOleObject('Excel.Application');
  try
    ovEA.Workbooks.Add;
    ovEA.Cells[1, 1] := 'OLE';

    // присваиваем ячейке значение
    ovCell := ovEA.Range['B1'];
    ovCell.Value := 'The BlackCat';

    // меняем шрифт 3 символов начиная с 1-го
    ovFont := ovCell.Characters(1, 3).Font;
    ovFont.Name := 'Arial Black';
    ovFont.Color := TColorRec.Red;

    // 5-й символ выделяем жирным
    ovCell.Characters(5, 1).Font.Bold := True;

    ovFont := ovCell.Characters(10, 3).Font;
    ovFont.Name := 'Comic Sans MS';
    ovFont.Color := RGB($4B, $00, $82); // Indigo

    ovEA.ActiveWorkbook.SaveAs('test.xlsx');
    ovEA.Quit;
  finally
    ovEA := Unassigned;
  end;
end;
    Теперь раскрасим ячейку в программе, которая работает с файлами MS Excel "напрямую" через библиотеку TMS FlexCel. Для этого у нее есть два способа.
    Первый способ – использование метода SetCellFromHtml. Этот метод присваивает ячейке строку в формате HTML, при этом теги форматирования HTML превращаются в форматированный текст MS Excel.
uses
  System.SysUtils, System.UITypes,
  VCL.FlexCel.Core, FlexCel.XlsAdapter;
  
procedure UseFlexCelHTML;
var
  xls: TExcelFile;
begin
  xls := TXlsFile.Create(True);
  try
    xls.Open('test.xlsx');

    xls.SetCellValue(2, 1, 'FlexCel HTML');
    xls.SetCellFromHtml(2, 2, 'The BlackCat');

    xls.Save('test.xlsx');
  finally
    xls.Free;
  end;
end;
Это способ прост в использовании, но имеет один существенный недостаток. Атрибут "size" тега "font" задает размер шрифта в условных единицах, что не позволяет корректно изменять размер шрифта в ячейке MS Excel.
    Второй способ – использование типа TRichString record. TRichString представляет собой строковое значение ячейки MS Excel в формате RTF. Для управления форматом строки TRichString используется массив или список элементов типа TRTFRun record. TRTFRun представляет собой структуру из двух полей: Font – шрифт и FirstChar – символ, с которого применяется шрифт (отсчет ведется с 0).
uses
  System.SysUtils, System.UITypes,
  VCL.FlexCel.Core, FlexCel.XlsAdapter;
  
procedure UseFlexCelRichString;
var
  xls: TExcelFile;
  xlsDefaultFont: TFlxFont;
  RtfRun: TRTFRunArray;
begin
  xls := TXlsFile.Create(True);
  try
    xls.Open('test.xlsx');

    xlsDefaultFont := xls.GetDefaultFont;
    xlsDefaultFont.Scheme := TFontScheme.None; // for TExcelFileFormat > v2003

    SetLength(RtfRun, 5);

    RtfRun[0].FirstChar := 0;
    RtfRun[0].Font := xlsDefaultFont;
    RtfRun[0].Font.Name := 'Arial Black';
    RtfRun[0].Font.Color := Colors.Red;

    RtfRun[1].FirstChar := 3;
    RtfRun[1].Font := xlsDefaultFont;

    RtfRun[2].FirstChar := 4;
    RtfRun[2].Font := xlsDefaultFont;
    RtfRun[2].Font.Style := [TFlxFontStyles.Bold];
    RtfRun[2].Font.Color := Colors.Black;

    RtfRun[3].FirstChar := 5;
    RtfRun[3].Font := xlsDefaultFont;
    RtfRun[3].Font.Color := Colors.Black;

    RtfRun[4].FirstChar := 9;
    RtfRun[4].Font := xlsDefaultFont;
    RtfRun[4].Font.Name := 'Comic Sans MS';
    RtfRun[4].Font.Color := TExcelColor.FromArgb($4B, $00, $82); // Indigo

    xls.SetCellValue(3, 1, 'FlexCel RTF');
    xls.SetCellValue(3, 2, TRichString.CreateWithoutCopy('The BlackCat', RtfRun));

    // увеличим размер шрифта на 2.5
    RtfRun[4].Font.Size20 := RtfRun[4].Font.Size20 + 50;
    xls.SetCellValue(4, 1, 'FlexCel RTF Size+2.5');
    xls.SetCellValue(4, 2, TRichString.CreateWithoutCopy('The BlackCat', RtfRun));

    xls.Save('test.xlsx');
  finally
    xls.Free;
  end;
end;
Этот способ требует написания большого количества команд, но он является более гибким и не требует составления строки в формате HTML. К тому же метод SetCellFromHtml сам использует TRichString:
procedure TXlsFile.SetCellFromHtml(const row: Int32; const col: Int32; 
                                   const htmlText: UTF16String; const XF: Int32);
var
  fmt: TFlxFormat;
  Rs: TRichString;
begin
  ...
  Rs := TRichString.FromHtml(htmlText, fmt, Self);
  SetCellValue(row, col, Rs, XF);
end;
ть     В процедуре UseOLE я создал файл test.xlsx, а в процедурах UseFlexCelHTML и UseFlexCelRichString его открывал и дополнял. Поэтому, если процедуры вставить в программу и выполнить последовательно
program xlsCellText;

{$APPTYPE CONSOLE}

uses
  System.SysUtils, System.UITypes,
  System.Variants, System.Win.ComObj, Winapi.Windows, Winapi.ActiveX,
  VCL.FlexCel.Core, FlexCel.XlsAdapter;

procedure UseOLE;
begin
  ...
end;

procedure UseFlexCelHTML;
begin
  ...
end;

procedure UseFlexCelRichString;
begin
  ...
end;

begin
  try
    UseOLE;
    UseFlexCelHTML;
    UseFlexCelRichString;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.
то получим такой результат:
Использование нескольких шрифтов и цветов в одной ячейке MS Excel одновременно
Как вы видите, несмотря на использование различных методов, текст в ячейках B1-B3 отформатирован одинаково. Отличается только ячейка B4 – в ней для слова "Cat" размер шрифта увеличен с 11 до 13.5.

Комментариев нет:

Отправить комментарий