Найти в Дзене

Lazarus: Как сохранить TStringGrid в JPG или PNG

Для автоматизации своей работы я создал и непрерывно дорабатываю программу в Lazarus IDE, с помощью которой формирую разные отчёты, разбираю файлы и т.п. Итоги я обычно вывожу в таблицу типа TStringGrid. Но если это надо только мне, то не вопрос. Однако часто приходится делиться этими отчётами с коллегами. Таблицу TStringGrid можно, например, сохранить в формате CSV. Это делается легко стандартными средствами примерно так: StringGrid.SaveToCSVFile('Файл таблицы.csv', ';'); Однако делиться отчётами часто приходится в Телеграм или МАХ, и на телефонах не у всех есть возможность посмотреть файл CSV, да и не всегда это удобно. Поэтому я обычно делаю копию экрана и отправляю в мессенджер картинку. Картинка там сразу видна - не надо ничего открывать. К тому же картинка цветная, где некоторые ячейки выделены цветом для лучшего понимая. Сделать копию экрана (скриншот) недолго и несложно. Однако всё равно это занимает время - надо сделать копию, обрезать лишнее (нужна ведь только часть окна, а

Для автоматизации своей работы я создал и непрерывно дорабатываю программу в Lazarus IDE, с помощью которой формирую разные отчёты, разбираю файлы и т.п. Итоги я обычно вывожу в таблицу типа TStringGrid. Но если это надо только мне, то не вопрос. Однако часто приходится делиться этими отчётами с коллегами.

Таблицу TStringGrid можно, например, сохранить в формате CSV. Это делается легко стандартными средствами примерно так:

StringGrid.SaveToCSVFile('Файл таблицы.csv', ';');

Однако делиться отчётами часто приходится в Телеграм или МАХ, и на телефонах не у всех есть возможность посмотреть файл CSV, да и не всегда это удобно. Поэтому я обычно делаю копию экрана и отправляю в мессенджер картинку. Картинка там сразу видна - не надо ничего открывать. К тому же картинка цветная, где некоторые ячейки выделены цветом для лучшего понимая.

Сделать копию экрана (скриншот) недолго и несложно. Однако всё равно это занимает время - надо сделать копию, обрезать лишнее (нужна ведь только часть окна, а не весь экран). Да, это занимает не больше минуты. Но всё равно это лишнее время и лишние движения. Поэтому разумно сделать возможность сохранения таблицы в файл изображения непосредственно из программы. И сегодня я покажу один из способов это сделать в Lazarus.

Итак, сначала надо подключить к программе следующие модули:

Graphics, LCLType, IntfGraphics, FPImage, FPWritePNG, FPWriteJPEG

Модуль Graphics в графическом приложении уже подключен. Остальные надо добавить.

Затем создаём примерно такую процедуру:

Ниже привожу текст, если кому-то понадобится скопировать:

procedure SaveGridAsImage(Grid : TStringGrid; const FileName : string;
IsPNG: Boolean = True);
var Bitmap : TBitmap;
i, j, x, y : Integer;
Rect : TRect;
MaxWidth, MaxHeight : Integer;
begin
// Если компилятор будет ругаться, то надо использовтаь
// полное имя Graphics.TBitmap.....
Bitmap := TBitmap.Create;
try
// Рассчитываем размеры
MaxWidth := 0;
MaxHeight := 0;
// Суммируем ширины колонок
for i := 0 to Grid.ColCount - 1 do Inc(MaxWidth, Grid.ColWidths[i]);
// Суммируем высоты строк (заголовок + данные)
for i := 0 to Grid.RowCount - 1 do Inc(MaxHeight, Grid.RowHeights[i]);
Bitmap.Width := MaxWidth;
Bitmap.Height := MaxHeight;
// Настраиваем фон
Bitmap.Canvas.Brush.Color := clWhite;
Bitmap.Canvas.FillRect(0, 0, Bitmap.Width, Bitmap.Height);
// Настраиваем шрифт
Bitmap.Canvas.Font := Grid.Font;
Bitmap.Canvas.Pen.Color := clBlack;
y := 0;
// Рисуем строки
for i := 0 to Grid.RowCount - 1 do
begin
x := 0;
// Рисуем колонки
for j := 0 to Grid.ColCount - 1 do
begin
Rect := Bounds(x, y, Grid.ColWidths[j], Grid.RowHeights[i]);
// Цвет фона ячейки (можно настроить)
// Светло-серый для заголовка
if i = 0 then Bitmap.Canvas.Brush.Color := $00E6E6E6
else Bitmap.Canvas.Brush.Color := clWhite;
Bitmap.Canvas.FillRect(Rect);
// Рамка ячейки
Bitmap.Canvas.Pen.Color := $00C0C0C0;
Bitmap.Canvas.Rectangle(Rect);
// Текст ячейки
Bitmap.Canvas.TextRect(Rect,
Rect.Left + 2,
Rect.Top + 2,
Grid.Cells[j, i]);
Inc(x, Grid.ColWidths[j]);
end;
Inc(y, Grid.RowHeights[i]);
end;
// Сохраняем в файл
if IsPNG then Bitmap.SaveToFile(ChangeFileExt(FileName, '.png'))
else Bitmap.SaveToFile(ChangeFileExt(FileName, '.jpg'));
finally
Bitmap.Free;
end;
end;

Ну вот и всё, в общем-то. Если надо сохранить как JPG, вызываем процедуру с IsPNG = FALSE. По умолчанию сохраняется в PNG:

-2

Ну и вот так выглядит тестовое приложение с результатом:

-3

Правда, здесь не решён вопрос сохранения цвета фона и текста ячеек, если таковой был установлен. Эта задача посложнее, и я расскажу о решении в следующий раз. Подписывайтесь на канал, чтобы ничего не пропустить.