Звонит юзеp oпеpатоpу АТС:
- Девушка! Мне тут какой-то совеpшенно дикий счет пpишел за услуги связи...
- Ваш номеp?
- 555-55-55
- Так... Все веpно. Это счет за секс-услуги по телефону.
- Да ты че! Я такой гадостью сpоду не занимался!
- Как? А неделю назад вы звонили Васе Пупкину по телефону 444-44-44 и пытались настpоить полуось?
type
TGridToHTMLOption = (ghWithHeaders);
TGridToHTMLOptions = setof TGridToHTMLOption;
function DBGridToHTML(Grid : TDBGrid;
ExportOptions: TGridToHTMLOptions): String;
const
HTMLStart =
'< !DOCTYPE HTML PUBLIC " -//W3C//DTD HTML 4.0 Transitional//EN" > '#13
+
'< HTML> '#13 +
'< HEAD> < META http-equiv=Content-Type content=" text/html;
charset=windows-1251" > '#13 +
'< STYLE> '#13 +
'BODY {'#13 +
' BACKGROUND: white;'#13 +
' COLOR: black;'#13 +
' FONT-FAMILY: arial;'#13 +
' FONT-SIZE: 8pt;'#13 +
' VERTICAL-ALIGN: top'#13 +
'}'#13 +
'TABLE {'#13 +
' BACKGROUND: white;'#13 +
' BORDER-BOTTOM: silver 0px solid;'#13 +
' BORDER-LEFT: silver 1px solid;'#13 +
' BORDER-RIGHT: silver 0px solid;'#13 +
' BORDER-TOP: silver 1px solid;'#13 +
' FONT-FAMILY: arial;'#13 +
' FONT-SIZE: 8pt;'#13 +
' FONT-WEIGHT: normal;'#13 +
'}'#13 +
'TD {'#13 +
' BORDER-BOTTOM: silver 1px solid;'#13 +
' BORDER-LEFT: silver 0px solid;'#13 +
' BORDER-RIGHT: silver 1px solid;'#13 +
' BORDER-TOP: silver 0px solid;'#13 +
' VERTICAL-ALIGN: top;'#13 +
' TEXT-ALIGN: left;'#13 +
'}'#13 +
'TD.grid {'#13 +
' TEXT-ALIGN: left;'#13 +
'}'#13 +
'TD.gridr {'#13 +
' TEXT-ALIGN: right;'#13 +
'}'#13 +
'TD.gridc {'#13 +
' TEXT-ALIGN: center;'#13 +
'}'#13 +
'TH {'#13 +
' BACKGROUND: silver;'#13 +
' BORDER-BOTTOM: gray 1px solid;'#13 +
' BORDER-LEFT: gray 0px solid;'#13 +
' BORDER-RIGHT: gray 1px solid;'#13 +
' BORDER-TOP: gray 0px solid;'#13 +
' FONT-WEIGHT: bold;'#13 +
'}'#13 +
'TH.grid {'#13 +
' TEXT-ALIGN: left;'#13 +
'}'#13 +
'TH.gridr {'#13 +
' TEXT-ALIGN: right;'#13 +
'}'#13 +
'TH.gridc {'#13 +
' TEXT-ALIGN: center;'#13 +
'}'#13 +
'< /STYLE> '#13 +
'< TITLE> Печать таблицы< /TITLE> '#13 +
'< /HEAD> '#13 +
'< BODY> '#13;
HTMLEnd = '< /BODY> < /HTML> ';
TableStart = '< TABLE WIDTH=" 100%" CELLSPACING=0 CELLPADDING=1> '#13;
TableEnd = '< /TABLE> '#13;
HeaderRowStart = '< TR> '#13;
HeaderRowEnd = '< /TR> '#13;
BodyRowStart = '< TR> '#13;
BodyRowEnd = '< /TR> '#13;
const
StyleNames: array [TAlignment] ofString = ('grid', 'gridr',
'gridc');
function TD(Column: TColumn; IsTitle: Boolean; Widht: Integer):
String;
var
S: String;
Align: TAlignment;
Tag: String;
beginif IsTitle thenbegin
Tag := 'TH';
Align := Column.Title.Alignment;
S := StyleNames[Align];
endelsebegin
Tag := 'TD';
Align := Column.Alignment;
if Align = taLeftJustify thenbeginif (Column.Field is TBCDField) or
(Column.Field is TCurrencyField) then
Align := taRightJustify;
if (Column.Field is TBooleanField) then
Align := taCenter;
end;
S := StyleNames[Align];
if (Column.Field is TBCDField) or (Column.Field is
TIntegerField) then
S := S + ' NOWRAP'
end;
if Widht > 0 then
S := S + Format(' WIDTH=" %d%%" ', [Widht]);
Result := '< ' + Tag + ' class=' + S + '> ';
if IsTitle thenbegin
S := Column.Title.Caption
endelsebeginif Column.Field is TBooleanField thenwith TBooleanField(Column.Field) dobeginif Length(DisplayValues) = 0 thenbeginif AsBoolean then
S := 'да'
else
S := 'нет';
endelse
S := Column.Field.DisplayText;
endelse
S := Column.Field.DisplayText;
end;
if Length(Trim(S)) = 0 then
S := ' ';
Result := Result + S + '< /' + Tag + '> '#13;
end;
var
BM : String;
I : Integer;
Widhts: arrayof Integer;
TotalWidht: Integer;
begin
Result := '';
with Grid dobeginif Assigned(DataSource) and
Assigned(DataSource.DataSet) and
DataSource.DataSet.Active thenwith DataSource.DataSet dobegin
DisableControls;
BM := BookMark;
SetLength(Widhts, Columns.Count);
TotalWidht := 0;
for I := 0 to Pred(Columns.Count) dobeginif Assigned(Columns[I].Field) thenbegin
Widhts[I] := Columns[I].Width;
Inc(TotalWidht, Widhts[I]);
end;
end;
for I := 0 to High(Widhts) dobegin
Widhts[I] := Widhts[I] * 100 div TotalWidht;
end;
Result := HTMLStart;
Result := Result + TableStart;
if (ghWithHeaders in ExportOptions) thenbegin
Result := Result + HeaderRowStart;
for I := 0 to Pred(Columns.Count) dobeginif Assigned(Columns.Items[I].Field) thenbegin
Result := Result + TD(Columns.Items[I], TRUE, Widhts[I]);
end;
end;
Result := Result + HeaderRowEnd;
end;
First;
whilenot Eof dobegin
Result := Result + BodyRowStart;
for I := 0 to Pred( Columns.Count ) dobeginif Assigned(Columns.Items[I].Field) thenbegin
Result := Result + TD(Columns.Items[I], FALSE,
-1{Integer(Widhts[Index]});
end;
end;
Result := Result + BodyRowEnd;
Next;
end;
Result := Result + TableEnd + HTMLEnd;
BookMark := BM;
EnableControls;
end;
end;
end;
Перевод на русский язык:
Код-snippet на Delphi, экспортирующий DBGrid в HTML. Функция DBGridToHTML принимает два параметра: объект TDBGrid и необязательный набор опций TGridToHTMLOptions, определяющий включение заголовков в вывод.
Функция инициализирует некоторые константы для HTML-шапки и подножки, а также стили для различных элементов таблицы. Затем она проходит по каждому столбцу грида, создавая таблицу с строками для заголовков и данных.
Для каждого ячейки в гриде функция вызывает функцию TD, генерирующую соответствующий код HTML. Эта функция принимает три параметра: объект TColumn, булевое значение, указывающее является ли это строка заголовка, и необязательное значение ширины.
Функция TD генерирует код HTML для ячейки таблицы на основе ее выравнивания и содержимого. Она также применяет стили из массива StyleNames, чтобы определить выравнивание и форматирование ячейки.
Наконец, функция DBGridToHTML конкатенирует все сгенерированные коды HTML в единый строку и возвращает ее как результат.
Вот некоторые улучшения, которые можно было бы сделать:
Код использует много hardcoded-строк для HTML-шапки и подножки. Рассмотрите возможность использования констант или XML-файла для хранения этих значений.
Функция TD имеет сложный логик для определения выравнивания ячейки на основе ее содержимого. Это можно упростить, введя более констант или enum для представления различных типов выравнивания.
Код не обрабатывает ошибки хорошо. Рассмотрите возможность добавления блоков try-except для ловли любых исключений, которые могут возникнуть во время процесса экспорта.
Код использует много повторяющегося кода для генерации строк и столбцов таблицы. Рассмотрите возможность рефакторинга этого кода в отдельные функции или циклы.
Код не предоставляет никаких опций для настройки процесса экспорта, таких как указание пути для вывода или управление форматированием HTML-вывода.
Вот пример того, как можно было бы рефакторить код, чтобы сделать его более модульным и легко поддерживаемым:
constcHTMLStart='<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">';cHTMLEnd='</BODY></HTML>';functionGenerateTableHeader(constColumns:TColumns;constOptions:TGridToHTMLOptions):String;beginResult:='';ifghWithHeadersinOptionsthenforI:=0toPred(Columns.Count)dobeginifAssigned(Columns.Items[I].Field)thenbeginResult:=Result+TD(Columns.Items[I],TRUE,-1);end;end;end;functionGenerateTableBody(constDataSet:TDataSet;constColumns:TColumns):String;beginResult:='';whilenotDataSet.EofdobeginResult:=Result+BodyRowStart;forI:=0toPred(Columns.Count)dobeginifAssigned(Columns.Items[I].Field)thenbeginResult:=Result+TD(Columns.Items[I],FALSE,-1);end;end;Result:=Result+BodyRowEnd;DataSet.Next;end;end;functionDBGridToHTML(constGrid:TDBGrid;constOptions:TGridToHTMLOptions):String;beginResult:='';withGriddobegin// ... (rest of the code remains the same)Result:=GenerateTableHeader(Columns,Options);Result:=GenerateTableBody(DataSet,Columns);// ... (rest of the code remains the same)end;end;
В этом рефакторированном коде функция DBGridToHTML разбита на две отдельные функции: GenerateTableHeader и GenerateTableBody. Каждая функция отвечает за генерацию конкретной части HTML-вывода, что делает ее более легко поддерживаемой и модульной.
Эта статья описывает функцию DBGridToHTML для экспорта данных из DBGrid в HTML-формат.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.