Экспорт чисел в Excel

отредактировано 01:47 Раздел: FastReport 3.0
Уважаемые разработчики, убедительная просьба внесите в очередной релиз
изменения в экспорт в Excel, в frxExportXML вообще не понятна работа функции
IsDigits, по моему это обычный ляп. Decimalseparator (для русского Excel) нужно заменить на "."
С приведенными ниже исправлениями у меня все работает, правда в OLE пока не получилось задать формат для
ячейки, а только для всей таблицы. в XML экспорте конечно нужно формиравать FormatList не в этом модуле,
а при формировании ExportStyles.

2. Format у Мемо поля я задаю в редакторе Мемо, но в Инспекторе объектов параметр DisplayFormat приходится
устанавливать вручную, нельзяли ввести параметр (а может уже есть), чтобы DisplayFormat заполнялся при
изменение формата в редакторе MEMO



************************* Так сейчас ********

unit frxExportXML;



function TfrxXMLExport.IsDigits(const Str: String): Boolean;
var
i: Integer;
begin
Result := True;
for i := 1 to Length(Str) do
if (Ord(Str) < 48) or (Ord(Str) > 57) or (Ord(Str) <> 46) then
begin
Result := False;
break;
end;
end;

...

procedure TfrxXMLExport.ExportPage(Stream: TStream);
begin

...

if (Obj.DisplayFormat.Kind = fkNumeric) and IsDigits(s) then
begin
s := StringReplace(s, ThousandSeparator, '', [rfReplaceAll]);
s := StringReplace(s, Obj.DisplayFormat.DecimalSeparator,
DecimalSeparator, [rfReplaceAll]);
si := ' ss:Type="Number"';
WriteExpLn('<Data' + si + '>' + s + '</Data>');
end

*************

************* Так у меня ********

function TfrxXMLExport.IsDigits(const Str: String): Boolean;
var
i: Integer;
begin
Result := True;
for i := 1 to Length(Str) do
if not((AnsiChar(Str) in ) or (Ord(Str)=160)) then
begin
Result := False;
break;
end;
end;


procedure TfrxXMLExport.ExportPage(Stream: TStream);
var
i, x, y, dx, dy, fx, fy, Page: Integer;
dcol, drow: Extended;
s, sb, si, su: String;
Vert, Horiz: String;
obj: TfrxIEMObject;
EStyle: TfrxIEMStyle;
St: String;
PageBreak: TStringList;

k, m, nn : integer;
FormatList: TStringList;

procedure WriteExpLn(const str: String);
begin
if Length(str) > 0 then
Stream.Write(str[1], Length(str));
Stream.Write(#13#10, 2);
end;

procedure AlignFR2AlignExcel(HAlign: TfrxHAlign; VAlign: TfrxVAlign;
var AlignH, AlignV: String);
begin
if HAlign = haLeft then
AlignH := 'Left'
else if HAlign = haRight then
AlignH := 'Right'
else if HAlign = haCenter then
AlignH := 'Center'
else if HAlign = haBlock then
AlignH := 'Justify'
else
AlignH := '';
if VAlign = vaTop then
AlignV := 'Top'
else if VAlign = vaBottom then
AlignV := 'Bottom'
else if VAlign = vaCenter then
AlignV := 'Center'
else
AlignV := '';
end;

{!!!!!!!!!!!!МОЕ}
function ConvertFormat(const fstr: string): string;
var
i, err, p : integer;
s: string;
begin
result := '';
if length(fstr)>0 then
begin
p := pos('.', fstr);
if p > 0 then
begin
s := Copy(fstr, p+1, length(fstr)-p-1);
val(s, p ,err);
end;
case fstr[length(fstr)] of
'n': begin
result := '#,##,0.';
for i := 1 to p do result := result + '0';
end;
'f': begin
result := '0.';
for i := 1 to p do result := result + '0';
end;
'd': begin
result := '#.';
for i := 1 to p do result := result + '#';
end;
end;
end;
end;
{!!!!!!!!!}

begin
PageBreak := TStringList.Create;

{!!!!!!!!}
FormatList := TStringList.Create;
nn:=1;
{!!!!!!!!!!}

if FShowProgress then
begin
FProgress := TfrxProgress.Create(nil);
FProgress.Execute(FMatrix.PagesCount, 'Exporting pages', True, True);
end;

WriteExpLn('<?xml version="1.0"?>');
WriteExpLn('<?mso-application progid="Excel.Sheet"?>');
WriteExpLn('<?fr-application created="' + UTF8Encode(FCreator) + '"?>');
WriteExpLn('<?fr-application homesite="http://www.fast-report.com"?>');
WriteExpLn('<Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"');
WriteExpLn(' xmlns:o="urn:schemas-microsoft-com:office:office"');
WriteExpLn(' xmlns:x="urn:schemas-microsoft-com:office:excel"');
WriteExpLn(' xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"');
WriteExpLn(' xmlns:html="http://www.w3.org/TR/REC-html40">');
WriteExpLn('<DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">');
WriteExpLn('<Title>' + UTF8Encode(Report.ReportOptions.Name) + '</Title>');
WriteExpLn('<Author>' + UTF8Encode(Report.ReportOptions.Author) + '</Author>');
WriteExpLn('<Created>' + DateToStr(Date) + 'T' + TimeToStr(Time) + 'Z</Created>');
WriteExpLn('<Version>' + UTF8Encode(Report.ReportOptions.VersionMajor) + '.' +
UTF8Encode(Report.ReportOptions.VersionMinor) + '.' +
UTF8Encode(Report.ReportOptions.VersionRelease) + '.' +
UTF8Encode(Report.ReportOptions.VersionBuild) + '</Version>');
WriteExpLn('</DocumentProperties>');
WriteExpLn('<ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">');
WriteExpLn('<ProtectStructure>False</ProtectStructure>');
WriteExpLn('<ProtectWindows>False</ProtectWindows>');
WriteExpLn('</ExcelWorkbook>');

if FExportStyles then
begin
WriteExpLn('<Styles>');
for x := 0 to FMatrix.StylesCount - 1 do
begin
EStyle := FMatrix.GetStyleById(x);
s := 's' + IntToStr(x);
WriteExpLn('<Style ss:ID="'+s+'">');
if fsBold in EStyle.Font.Style then
sb := ' ss:Bold="1"'
else
sb := '';
if fsItalic in EStyle.Font.Style then
si := ' ss:Italic="1"'
else
si := '';
if fsUnderline in EStyle.Font.Style then
su := ' ss:Underline="Single"'
else
su := '';
WriteExpLn('<Font '+
'ss:FontName="' + EStyle.Font.Name + '" '+
'ss:Size="' + IntToStr(EStyle.Font.Size) + '" ' +
'ss:Color="' + HTMLRGBColor(EStyle.Font.Color) + '"' + sb + si + su + '/>');
WriteExpLn('<Interior ss:Color="' + HTMLRGBColor(EStyle.Color) +
'" ss:Pattern="Solid"/>');
AlignFR2AlignExcel(EStyle.HAlign, EStyle.VAlign, Horiz, Vert);
if (EStyle.Rotation > 0) and (EStyle.Rotation <= 90) then
s := 'ss:Rotate="' + IntToStr(EStyle.Rotation) + '"'
else if (EStyle.Rotation < 360) and (EStyle.Rotation >= 270) then
s := 'ss:Rotate="' + IntToStr(EStyle.Rotation - 360) + '"'
else
s := '';
si := '" ss:WrapText="1" ';
WriteExpLn('<Alignment ss:Horizontal="' + Horiz + '" ss:Vertical="' + Vert + si + s +'/>');

WriteExpLn('<Borders>');
if EStyle.FrameWidth > 1 then
i := 3
else
i := 1;
s := 'ss:Weight="' + IntToStr(i) + '" ';
si := 'ss:Color="' + HTMLRGBColor(EStyle.FrameColor) + '" ';
if (ftLeft in EStyle.FrameTyp) then
WriteExpLn('<Border ss:Position="Left" ss:LineStyle="Continuous" ' + s + si + '/>');
if (ftRight in EStyle.FrameTyp) then
WriteExpLn('<Border ss:Position="Right" ss:LineStyle="Continuous" ' + s + si + '/>');
if (ftTop in EStyle.FrameTyp) then
WriteExpLn('<Border ss:Position="Top" ss:LineStyle="Continuous" ' + s + si + '/>');
if (ftBottom in EStyle.FrameTyp) then
WriteExpLn('<Border ss:Position="Bottom" ss:LineStyle="Continuous" ' + s + si + '/>');
WriteExpLn('</Borders>');

{!!!!!! МОE общее значение по умолчанию}
WriteExpLn('<NumberFormat ss:Format="#,##0.00"/>');
{!!!!!!!!!!!!}

WriteExpLn('</Style>');
if x=0 then
for k := 0 to FMatrix.Height - 2 do
for y := 0 to FMatrix.Width - 1 do
begin
m := FMatrix.GetCell(k, y);
if (m <> -1) then
begin
Obj := FMatrix.GetObjectById(m);
if (Obj.DisplayFormat.Kind = fkNumeric) and
(Obj.DisplayFormat.FormatStr <> '') and
(Obj.DisplayFormat.FormatStr <> '%2.2n') and
(FormatList.IndexOfName(Obj.DisplayFormat.FormatStr)<0) then
begin
s := 's2000'+IntToStr(nn);
WriteExpLn('<Style ss:ID="'+s+'">');
WriteExpLn('<NumberFormat ss:Format="'+ConVertFormat(Obj.DisplayFormat.FormatStr)+'"/>');
WriteExpLn('</Style>');
FormatList.Add(Obj.DisplayFormat.FormatStr+'='+s);
inc(nn);
end;
end;
end;

end;
WriteExpLn('</Styles>');
end;

s := 'Page 1';
WriteExpLn('<Worksheet ss:Name="' + UTF8Encode(s) + '">');
WriteExpLn('<Table ss:ExpandedColumnCount="' + IntToStr(FMatrix.Width) + '"' +
' ss:ExpandedRowCount="' + IntToStr(FMatrix.Height) + '" x:FullColumns="1" x:FullRows="1">');
for x := 1 to FMatrix.Width - 1 do
begin
dcol := (FMatrix.GetXPosById(x) - FMatrix.GetXPosById(x - 1)) / Xdivider;
WriteExpLn('<Column ss:AutoFitWidth="0" ss:Width="' +
frFloat2Str(dcol, 2) + '"/>');
end;
st := '';
Page := 0;

for y := 0 to FMatrix.Height - 2 do
begin
drow := (FMatrix.GetYPosById(y + 1) - FMatrix.GetYPosById(y)) / Ydivider;
WriteExpLn('<Row ss:Height="' + frFloat2Str(drow, 2) + '">');
if FMatrix.PagesCount > Page then
if FMatrix.GetYPosById(y) >= FMatrix.GetPageBreak(Page) then
begin
Inc(Page);
PageBreak.Add(IntToStr(y + 1));
if FShowProgress then
begin
FProgress.Tick;
if FProgress.Terminated then
break;
end;
end;
for x := 0 to FMatrix.Width - 1 do
begin
if FShowProgress then
if FProgress.Terminated then
break;
si := ' ss:Index="' + IntToStr(x + 1) + '" ';
i := FMatrix.GetCell(x, y);
if (i <> -1) then
begin
Obj := FMatrix.GetObjectById(i);
if Obj.Counter = 0 then
begin
FMatrix.GetObjectPos(i, fx, fy, dx, dy);
Obj.Counter := 1;
if Obj.IsText then
begin
if dx > 1 then
begin
s := 'ss:MergeAcross="' + IntToStr(dx - 1) + '" ';
Inc(dx);
end
else
s := '';
if dy > 1 then
sb := 'ss:MergeDown="' + IntToStr(dy - 1) + '" '
else
sb := '';
if FExportStyles then
begin

{!!!!!!!!!МОЕ}
if (Obj.DisplayFormat.Kind = fkNumeric) and
(Obj.DisplayFormat.FormatStr <> '') and
(Obj.DisplayFormat.FormatStr <> '%2.2n') then
st := 'ss:StyleID="' + FormatList.Values[Obj.DisplayFormat.FormatStr] + '" '

else
{!!!!!!!!!!!}

st := 'ss:StyleID="' + 's' + IntToStr(Obj.StyleIndex) + '" '
end
else
st := '';
WriteExpLn('<Cell' + si + s + sb + st + '>');
s := TruncReturns(Obj.Memo.Text);
if (Obj.DisplayFormat.Kind = fkNumeric) and IsDigits(s) then
begin
s := StringReplace(s, ThousandSeparator, '', [rfReplaceAll]);

{!!!!!!! МОЕ}
s := StringReplace(s, ',', '.', [rfReplaceAll]);
{!!!!!!! }

si := ' ss:Type="Number"';
WriteExpLn('<Data' + si + '>' + s + '</Data>');
end
else
begin
si := ' ss:Type="String"';
s := ChangeReturns(s);
WriteExpLn('<Data' + si + '>' + UTF8Encode(s) + '</Data>');
end;
WriteExpLn('</Cell>');
end;
end
end
else
WriteExpLn('<Cell' + si + '/>');
end;
WriteExpLn('</Row>');
end;

WriteExpLn('</Table>');
WriteExpLn('<WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">');
WriteExpLn('<PageSetup>');
if FPageOrientation = poLandscape then
WriteExpLn('<Layout x:Orientation="Landscape"/>');
WriteExpLn('<PageMargins x:Bottom="' + frFloat2Str(FPageBottom / MargDiv, 2) +
'" x:Left="' + frFloat2Str(FPageLeft / MargDiv, 2) +
'" x:Right="' + frFloat2Str(FPageRight / MargDiv, 2) +
'" x:Top="' + frFloat2Str(FPageTop / MargDiv, 2) + '"/>');
WriteExpLn('</PageSetup>');
WriteExpLn('</WorksheetOptions>');

if FExportPageBreaks then
begin
WriteExpLn('<PageBreaks xmlns="urn:schemas-microsoft-com:office:excel">');
WriteExpLn('<RowBreaks>');
for i := 0 to FMatrix.PagesCount - 2 do
begin
WriteExpLn('<RowBreak>');
WriteExpLn('<Row>' + PageBreak + '</Row>');
WriteExpLn('</RowBreak>');
end;
WriteExpLn('</RowBreaks>');
WriteExpLn('</PageBreaks>');
end;
WriteExpLn('</Worksheet>');
WriteExpLn('</Workbook>');
PageBreak.Free;

{!!!!!!!!!МОЕ}
FormatList.Free;
{!!!!!!!}

if FShowProgress then
FProgress.Free;
end;

******************


*******************Экспорт в XLS ******************

unit frxExportXLS;



procedure TfrxXLSExport.ExportPage_Fast;
begin

.......

s := CleanReturns(Obj.Memo.Text);
if Length(s) > XLMaxChars then
s := Copy(s, 1, XLMaxChars);

{!!!!!МОЁ}
if not FAsText then
if Obj.DisplayFormat.Kind=fkNumeric then
begin
s := StringReplace(s, ThousandSeparator, '', [rfReplaceAll]);
s := StringReplace(s, ',', '.', [rfReplaceAll]);
end
else
if (Obj.DisplayFormat.Kind=fkText) then
s := '''' + s;
{!!!!!!!}

if FAsText then
s := '''' + s;
ArrData^[y + FMatrix.Height * (x - 1)] := s;

.....


FExcel.SetRange(1, 1, FMatrix.Width , FMatrix.Height);

{!!!!!!!МОЁ}
FExcel.Range.NumberFormat := '# ##0,00'; {на всю ведомость}
{!!!!!!!!}

FExcel.Range.Value := ExlArray;
FExcel.WorkSheet.Cells.WrapText := True;
if ShowProgress then
FProgress.Free;
end;

На каждую ячейку пока не получилось Excel не реагирует.

Комментарии

  • отредактировано 01:47
    Извиняюсь за неточность
    в ExportXLS

    if not FAsText then
    if Obj.DisplayFormat.Kind=fkNumeric then
    begin
    s := StringReplace(s, ThousandSeparator, '', [rfReplaceAll]);

    s := StringReplace(s, ',', '.', [rfReplaceAll]); {для Office 2003}
    или
    s := StringReplace(s, DecimalSeparotor, ',', [rfReplaceAll]); {для Office 2000}

    end
    else
    if (Obj.DisplayFormat.Kind=fkText) then s := '''' + s;
  • отредактировано 01:47
    Вот кусок кода для XLSExport проверил на Excel2000, XP, 2003.
    Проблемы только с Итогами в CrossTAB не удалось установить свойства DisplayFormat, перед печатью уже поздно
    нужно перед формированием, а это вопрос к разработчикам.
    В XML экспорт допустил ошибку нужно в function ConvertFormat
    result := '#,##0.'; а не result := '#,##,0.';
    делал на ночью на скорую руку, нужен был срочно экспорт в Excel2003, заработало, а другие варианты проверял позже.

    ************************
    procedure TfrxXLSExport.ExportPage_Fast;
    var
    i, fx, fy, x, y, dx, dy: Integer;
    dcol, drow: Extended;
    s: OLEVariant;
    Vert, Horiz: Integer;
    ExlArray: Variant;

    obj: TfrxIEMObject;
    EStyle: TfrxIEMStyle;
    XStyle: Variant;
    Pic: TPicture;
    PicFormat: Word;
    PicData: Cardinal;
    PicPalette: HPALETTE;
    PicCount: Integer;
    PBreakCounter: Integer;
    RowSizes: array of Currency;
    RowSizesCount: array of Integer;
    imc: Integer;
    ArrData: PArrData;
    j: Integer;
    FixRow: String;
    CurRowSize: Integer;
    CurRangeCoord: String;
    vRowsToSizes: TStrings;
    vCellStyles: TStrings;
    vCellFormats: TStringList;
    vCellFrames: TStrings;
    vCellMerges: TStrings;

    fs: string;
    ind: integer;

    {!!!!!!!!!!!!МОЕ}
    function ConvertFormat(const fstr: string): string;
    var
    i, err, p : integer;
    s: string;
    begin
    result := '';
    if length(fstr)>0 then
    begin
    p := pos('.', fstr);
    if p > 0 then
    begin
    s := Copy(fstr, p+1, length(fstr)-p-1);
    val(s, p ,err);
    end;
    case fstr[length(fstr)] of
    'n': begin
    result := '# ##0,';
    for i := 1 to p do result := result + '0';
    end;
    'f': begin
    result := '0,';
    for i := 1 to p do result := result + '0';
    end;
    'd': begin
    result := '#,';
    for i := 1 to p do result := result + '#';
    end;
    end;
    end;
    end;
    {!!!!!!!!!111111}

    procedure AlignFR2AlignExcel(HAlign: TfrxHAlign; VAlign: TfrxVAlign; var AlignH, AlignV: integer);
    begin
    if HAlign = haLeft then
    AlignH := xlLeft
    else if HAlign = haRight then
    AlignH := xlRight
    else if HAlign = haCenter then
    AlignH := xlCenter
    else if HAlign = haBlock then
    AlignH := xlJustify
    else
    AlignH := xlLeft;

    if VAlign = vaTop then
    AlignV := xlTop
    else if VAlign = vaBottom then
    AlignV := xlBottom
    else if VAlign = vaCenter then
    AlignV := xlCenter
    else
    AlignV := xlTop;
    end;

    function RoundSizeY(const Value: Extended; xlSizeYRound: Currency): Currency;
    begin
    Result := Round(Value / xlSizeYRound) * xlSizeYRound
    end;

    function GetSizeIndex(const aSize: Currency): integer;
    var
    i: integer;
    c: integer;
    begin
    c := Length(RowSizes);
    for i := 0 to c - 1 do
    begin
    if RowSizes = aSize then
    begin
    Result := i;
    RowSizesCount := RowSizesCount + 1;
    Exit
    end;
    end;
    SetLength(RowSizes, c + 1);
    SetLength(RowSizesCount,c + 1);
    RowSizes[c] := aSize;
    RowSizesCount[c] := 1;
    Result := c
    end;

    begin
    PicCount := 0;
    FExcel.SetPageMargin(FPageLeft, FPageRight, FPageTop, FPageBottom, FPageOrientation);

    if ShowProgress then
    begin
    FProgress := TfrxProgress.Create(self);
    FProgress.Execute(FMatrix.Height - 1, frxResources.Get('ProgressRows') + ' - 1', True, True);
    end
    else FProgress := nil;

    PBreakCounter := 0;

    FixRow := 'A1';
    CurRowSize := 0;
    vRowsToSizes := TStringList.Create;
    try
    vRowsToSizes.Capacity := FMatrix.Height;
    imc := 0;
    for y := 1 to FMatrix.Height - 1 do
    begin
    if ShowProgress then
    begin
    if FProgress.Terminated then
    break;
    FProgress.Tick;
    end;

    if (FMatrix.GetCellYPos(y) >= FMatrix.GetPageBreak(PBreakCounter)) and FpageBreaks then
    begin
    FExcel.WorkSheet.Rows[y + 2].PageBreak := xlPageBreakManual;
    Inc(PBreakCounter);
    end;

    drow := (FMatrix.GetYPosById(y) - FMatrix.GetYPosById(y - 1)) / Ydivider;
    j := GetSizeIndex(RoundSizeY(drow, xlSizeYRound));
    if RowSizesCount[j] > RowSizesCount[imc] then
    imc := j;
    if y > 1 then
    begin
    if j <> CurRowSize then
    begin
    if FixRow <> 'A' + IntToStr(y - 1) then
    CurRangeCoord := FixRow + ':A' + IntToStr(y - 1)
    else
    CurRangeCoord := FixRow;
    i := GetNewIndex(vRowsToSizes, CurRowSize);
    vRowsToSizes.InsertObject(i, CurRangeCoord, TObject(CurRowSize));
    FixRow := 'A' + IntToStr(y);
    CurRowSize := j;
    end;
    end;
    if y = FMatrix.Height - 1 then
    begin
    CurRangeCoord := FixRow + ':A' + IntToStr(y);
    i := GetNewIndex(vRowsToSizes, j);
    vRowsToSizes.InsertObject(i, CurRangeCoord, TObject(j));
    end;
    end;
    FExcel.SetRowsSize(vRowsToSizes, RowSizes, imc, FMatrix.Height, FProgress)
    finally
    vRowsToSizes.Free;
    end;

    if ShowProgress then
    if not FProgress.Terminated then
    FProgress.Execute(FMatrix.Width - 1, frxResources.Get('ProgressColumns'), True, True);

    for x := 1 to FMatrix.Width - 1 do
    begin
    if ShowProgress then
    begin
    if FProgress.Terminated then
    break;
    FProgress.Tick;
    end;
    dcol := (FMatrix.GetXPosById(x) - FMatrix.GetXPosById(x - 1)) / Xdivider;
    FExcel.SetColSize(x, dcol);
    end;

    if ShowProgress then
    if not FProgress.Terminated then
    FProgress.Execute(FMatrix.StylesCount - 1, frxResources.Get('ProgressStyles'), True, True);

    for x := 0 to FMatrix.StylesCount - 1 do
    begin
    if ShowProgress then
    begin
    if FProgress.Terminated then break;
    FProgress.Tick;
    end;
    EStyle := FMatrix.GetStyleById(x);
    s := 'S' + IntToStr(x);
    XStyle := FExcel.Excel.ActiveWorkbook.Styles.Add(s);
    XStyle.Font.Bold := fsBold in EStyle.Font.Style;
    XStyle.Font.Italic := fsItalic in EStyle.Font.Style;
    XStyle.Font.Underline := fsUnderline in EStyle.Font.Style;;
    XStyle.Font.Name := EStyle.Font.Name;
    XStyle.Font.Size := EStyle.Font.Size;
    XStyle.Font.Color:= EStyle.Font.Color;
    XStyle.Interior.Color := EStyle.Color;
    if (EStyle.Rotation > 0) and (EStyle.Rotation <= 90) then
    XStyle.Orientation := EStyle.Rotation
    else
    if (EStyle.Rotation < 360) and (EStyle.Rotation >= 270) then
    XStyle.Orientation := EStyle.Rotation - 360;

    AlignFR2AlignExcel(EStyle.HAlign, EStyle.VAlign, Horiz, Vert);
    XStyle.VerticalAlignment := Vert;
    XStyle.HorizontalAlignment := Horiz;
    Application.ProcessMessages;
    end;
    ExlArray := VarArrayCreate([1, FMatrix.Height , 1, FMatrix.Width ], varVariant);
    if ShowProgress then
    if not FProgress.Terminated then
    FProgress.Execute(FMatrix.Height, frxResources.Get('ProgressObjects'), True, True);
    ArrData := VarArrayLock(ExlArray) ;
    vCellStyles := TStringList.Create;
    vCellFormats := TStringList.Create;
    vCellFormats.Sorted := true;
    vCellFrames := TStringList.Create;
    vCellMerges := TStringList.Create;
    try
    for y := 1 to FMatrix.Height do
    begin
    if ShowProgress then
    begin
    if FProgress.Terminated then
    Break;
    FProgress.Tick;
    end;
    for x := 1 to FMatrix.Width do
    begin
    i := FMatrix.GetCell(x - 1, y - 1);
    if i <> -1 then
    begin
    Obj := FMatrix.GetObjectById(i);
    if Obj.Counter = 0 then
    begin
    Obj.Counter := 1;
    FMatrix.GetObjectPos(i, fx, fy, dx, dy);
    with FExcel do
    if (dx > 1) or (dy > 1) then
    CurRangeCoord := IntToCoord(x, y)+ ':' +
    IntToCoord(x + dx - 1, y + dy - 1)
    else
    CurRangeCoord := IntToCoord(x, y);
    if FExportStyles then
    begin
    j := GetNewIndex(vCellStyles, Obj.StyleIndex);
    vCellStyles.InsertObject(j, CurRangeCoord, TObject(Obj.StyleIndex));
    end;

    if FMergeCells then
    if (dx > 1) or (dy > 1) then
    vCellMerges.Add(CurRangeCoord);
    if FExportStyles then
    begin
    i := FrameTypesToByte(obj.Style.FrameTyp);
    if i <> 0 then
    begin
    j := GetNewIndex(vCellFrames, i);
    vCellFrames.InsertObject(j, CurRangeCoord, TObject(i));
    end;
    end;



    s := CleanReturns(Obj.Memo.Text);
    if Length(s) > XLMaxChars then
    s := Copy(s, 1, XLMaxChars);
    {!!!!!МОЁ}
    if not FAsText then
    if (Obj.DisplayFormat.Kind=fkNumeric) then
    begin
    if length(s) > 0 then
    begin
    s := StringReplace(s, ThousandSeparator, '', [rfReplaceAll]);
    s := StringReplace(s, ',', ',', [rfReplaceAll]);
    if (Obj.DisplayFormat.FormatStr <> '') then
    vCellFormats.Add(ConVertFormat(Obj.DisplayFormat.FormatStr)+'='+FExcel.IntToCoord(x, y))
    end
    end
    else
    if (Obj.DisplayFormat.Kind=fkText) then
    s := '''' + s;
    {!!!!!!!}

    if FAsText then
    s := '''' + s;
    ArrData^[y + FMatrix.Height * (x - 1)] := s;

    if not Obj.IsText then
    begin
    FExcel.SetRange(x, y, dx, dy);
    Inc(PicCount);
    Pic := TPicture.Create;
    Pic.Bitmap.Assign(Obj.Image);
    Pic.SaveToClipboardFormat(PicFormat, PicData, PicPalette);
    Clipboard.SetAsHandle(PicFormat,THandle(PicData));
    FExcel.Range.PasteSpecial(EmptyParam, EmptyParam, EmptyParam, EmptyParam);
    FExcel.WorkSheet.Pictures[PicCount].Left := FExcel.WorkSheet.Pictures[PicCount].Left + 1;
    FExcel.WorkSheet.Pictures[PicCount].Top := FExcel.WorkSheet.Pictures[PicCount].Top + 1;
    FExcel.WorkSheet.Pictures[PicCount].Width := Pic.Width / 1.38;
    FExcel.WorkSheet.Pictures[PicCount].Height := Pic.Height/ 1.38;
    Pic.Free;
    end;
    end;
    end;
    end;
    end;

    if FExportStyles then
    begin
    FExcel.ApplyStyles(vCellStyles, 0, FProgress);
    FExcel.ApplyStyles(vCellFrames, 1, FProgress);
    {!!!!!}
    FExcel.ApplyFormats(vCellFormats, FProgress);
    {!!!!!}
    end;
    if FMergeCells then
    FExcel.ApplyStyles(vCellMerges, 2, FProgress);
    finally
    VarArrayUnlock(ExlArray);
    vCellStyles.Free;
    vCellFormats.Free;
    vCellFrames.Free;
    vCellMerges.Free;
    end;
    FExcel.SetRange(1, 1, FMatrix.Width , FMatrix.Height);
    FExcel.Range.Value := ExlArray;
    FExcel.WorkSheet.Cells.WrapText := True;
    if ShowProgress then
    FProgress.Free;
    end;

    ...

    ...
    //добавил 2 процедуры

    procedure TfrxExcel.ApplyFormats(aRanges: TStringlist; aProgress: TfrxProgress);
    var
    i: integer;
    s: string;
    curFormat: string;
    begin
    if aRanges.Count > 0 then
    begin
    if Assigned(aProgress) then
    if not aProgress.Terminated then
    begin
    aProgress.Execute(aRanges.Count, 'Форматы данных', True, True);
    s := aRanges.ValueFromIndex[0];
    curFormat := aRanges.Names[0];
    for i := 1 to Pred(aRanges.Count) do
    begin
    if Assigned(aProgress) then
    begin
    if aProgress.Terminated then
    Break;
    aProgress.Tick;
    end;
    if aRanges.Names <> CurFormat then
    begin
    ApplyFormat(s, CurFormat);
    CurFormat := aRanges.Names;
    s := aRanges.ValueFromIndex;
    end
    else if Length(s) + Length(aRanges.ValueFromIndex) + 1 > 255 then
    begin
    ApplyFormat(s, CurFormat);
    s := aRanges.ValueFromIndex;
    end
    else s := s + ListSeparator + aRanges.ValueFromIndex
    end;
    ApplyFormat(s, CurFormat);
    end
    end;
    end;

    procedure TfrxExcel.ApplyFormat(const RangeCoord, aFormat: String);
    begin
    if Length(RangeCoord) > 0 then
    try
    WorkSheet.Range[RangeCoord].NumberFormat := aFormat;
    except
    end;
    end;

    **************************

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

Многофункциональный текстовый редактор. Чтобы отредактировать стиль параграфа, нажмите TAB, чтобы перейти к меню абзаца. Там вы можете выбрать стиль. По умолчанию не выбран ни один стиль. Когда вы выберете текст, появится встроенное меню форматирования. Нажмите TAB, чтобы войти в него. Некоторые элементы, такие как многофункциональные вставки ссылок, картинок, индикаторов загрузки и сообщений об ошибок могут быть вставлены в редактор. Вы можете перемещаться по ним, используя стрелки внутри редактора и удалять с помощью клавиш delete или backspace.