19 августа 2021

Разделение по диагонали ячейки MS Excel с двумя значениями

    Существует много способов разнообразить внешний вид таблицы в MS Excel. Например, иногда таблица может стать более наглядной, если в одной ячейке разместить сразу два значения, разделив ее по диагонали на две части. Одним из вариантов использования такой ячейки является шапка таблицы, в ячейке которой сразу два заголовка – для строк и для столбцов.
Таблица MS Excel с разделением ячейки по диагонали
    Давайте посмотрим, как MS Excel рисует диагональные границы ячейки.
Диагональные границы ячейки MS Excel
Как вы видите, в ячейке A1 просто перечеркнутый текст, который не похож на нужный нам заголовок. Что бы "красиво" разместить сразу два значения в одной ячейке необходимо скомбинировать текст ячейки с пробелами, переводом строки (#10) и невидимым символом (#0). Как это сделать я продемонстрирую с использованием библиотеки TMS FlexCel.
program xlsDiagonalBorder;

{$APPTYPE CONSOLE}

uses
  System.SysUtils,
  VCL.FlexCel.Core, FlexCel.XlsAdapter, FlexCel.Render;

procedure Test;
var
  xls: TExcelFile;
  fmt: TFlxFormat;
  ApplyFormat: TFlxApplyFormat;
begin
  xls := TXlsFile.Create(1, True);
  try
    // заполним заголовки строк и столбцов таблицы
    for var i := 1 to 5 do
      begin
        xls.SetCellValue(i + 1, 1, 'row ' + i.ToString);
        xls.SetCellValue(1, i + 1, 'col ' + i.ToString);
      end;

    // формат ячейки по умолчанию
    fmt := xls.GetDefaultFormat;
    // выравнивание по вертикали = по центру
    fmt.VAlignment := TVFlxAlignment.center;
    // выравнивание по горизонтали = по центру
    fmt.HAlignment := THFlxAlignment.center;
    // граница ячейки со всех сторон
    fmt.Borders.Left.Style  := TFlxBorderStyle.Thin;
    fmt.Borders.Right.Style := TFlxBorderStyle.Thin;
    fmt.Borders.Top.Style   := TFlxBorderStyle.Thin;
    fmt.Borders.Bottom.Style:= TFlxBorderStyle.Thin;

    // укажем, какие атрибуты формата будут применяться
    ApplyFormat := TFlxApplyFormat.Create;
    // отключим все атрибуты
    ApplyFormat.SetAllMembers(False);
    // включим границы
    ApplyFormat.Borders.SetAllMembers(True);
    // включим выравнивание
    ApplyFormat.VAlignment := True;
    ApplyFormat.HAlignment := True;

    ApplyFormat.Indent := True;

    // применим формат ко всем ячейкам таблицы
    xls.SetCellFormat(1, 1, 6, 6, fmt, ApplyFormat);

    // дополним формат диагональной границей
    fmt.Borders.Diagonal := TFlxOneBorder.Create(TFlxBorderStyle.Thin, TExcelColor.Automatic);
    // диагональная линия, идущая из левого верхнего угла в правый нижний
    fmt.Borders.DiagonalStyle := TFlxDiagonalBorder.DiagDown;

    // выравнивание по горизонтали = равномерно (отступ)
    fmt.HAlignment := THFlxAlignment.distributed;
    // что бы текст не прилипал к границе ячейки сделаем отступ
    fmt.Indent := 1;
    // применим формат к ячейке A1
    xls.SetCellFormat(1, 1, 1, 1, fmt, ApplyFormat);
    // заполним ячейку A1 заголовками столбцов и строк
    xls.SetCellValue(1, 1, #0' col'#10'row '#0);

    // диагональная линия, идущая из левого нижнего угла в правый верхний
    fmt.Borders.DiagonalStyle := TFlxDiagonalBorder.DiagUp;
    // применим формат к ячейке D1
    xls.SetCellFormat(1, 4, 6, 4, fmt, ApplyFormat);
    // заполним ячейку D1 заголовком
    xls.SetCellValue(1, 4, 'min '#0#10' max ');
    // заполним ячейки столбца D парными значениями
    for var iRow := 2 to 6 do
      xls.SetCellValue(iRow, 4, FormatFloat('0.0', iRow * 3.4) + ' '#0#10' ' + (iRow * 20).ToString + ' ');

    // перечеркнем правую нижнюю ячейку таблицы (F6)
    fmt.Borders.DiagonalStyle := TFlxDiagonalBorder.Both;
    // жирным диагональным крестом
    fmt.Borders.Diagonal.Style := TFlxBorderStyle.Medium;
    xls.SetCellFormat(6, 6, 6, 6, fmt, ApplyFormat);

    xls.Save('test.xlsx');
  finally
    xls.Free;
  end;
end;

begin
  try
    Test;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.
Все пояснения к тексту программы есть в комментариях. Поэтому обращу ваше внимание только на свойство Borders.DiagonalStyle (стиль диагональной границы ячейки), которое может принимать следующие значения (TFlxDiagonalBorder):
  • None – без диагональной линии (по умолчанию);
  • DiagDown – диагональная линия, идущая из левого верхнего угла в правый нижний;
  • DiagUp – диагональная линия, идущая из левого нижнего угла в правый верхний;
  • Both – обе диагональные линии (крест).
Приведенный мной способ заполнения ячейки двумя значениями позволяет сохранить форматирование даже при изменении размера строки или столбца:
Таблица MS Excel с разделением ячейки по диагонали

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

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