export delphi stringgrid to excel

后端 未结 3 1044
盖世英雄少女心
盖世英雄少女心 2020-12-06 07:09

I\'m trying to export data from a stringgrid in delphi 7 to microsoft excel. I have been using this code to do it:

  objExcel := TExcelApplication.Create(nil         


        
相关标签:
3条回答
  • 2020-12-06 07:45

    The problem is that you are calling the Excel object for every cell; this is a slow operation at the best of times, so doing this for a large number of cells is going to take a long time. I had a case of this not so long ago: 4000 rows with 9 columns took about 44 seconds to transfer to Excel.

    My current solution involves creating a csv file then importing that csv into Excel.

    const
     fn = 'c:\windows\temp\csv.csv';
    
    var
     csv: tstringlist;
     row, col: integer;
     s: string;
    
    begin
     csv:= tstringlist.create;
     for row:= 1 to stringgrid1.rowcount do 
      begin
       s:= '';
       for col:= 0 to stringgrid1.ColCount-1 do 
        s:= s + stringgrid1.Cells[col, row-1] + ',';
       csv.add (s)
      end;
    
     csv.savetofile (fn);
     csv.free;
    
     objExcel := TExcelApplication.Create(nil);
     objExcel.workbooks.open (fn);
     deletefile (fn);
    end;
    

    Another way comes from Mike Shkolnik which I am quoting as is:

    var
     xls, wb, Range: OLEVariant;
     arrData: Variant;
    
    begin
    {create variant array where we'll copy our data}
     arrData := VarArrayCreate([1, yourStringGrid.RowCount, 1, yourStringGrid.ColCount], varVariant);
    
     {fill array}
     for i := 1 to yourStringGrid.RowCount do
      for j := 1 to yourStringGrid.ColCount do
       arrData[i, j] := yourStringGrid.Cells[j-1, i-1];
    
     {initialize an instance of Excel}
     xls := CreateOLEObject('Excel.Application');
    
     {create workbook}
     wb := xls.Workbooks.Add;
    
     {retrieve a range where data must be placed}
     Range := wb.WorkSheets[1].Range[wb.WorkSheets[1].Cells[1, 1],
                                  wb.WorkSheets[1].Cells[yourStringGrid.RowCount, yourStringGrid.ColCount]];
    
     {copy data from allocated variant array}
     Range.Value := arrData;
    
     {show Excel with our data}
     xls.Visible := True;
    end;
    

    I suggest that you try both methods and see which is faster for your purposes.

    0 讨论(0)
  • 2020-12-06 08:02

    The quickest way is to use an array of Variant,and just pass the entire array to Excel:

    uses OleAuto;
    
    var
      xls, wb, Range: OLEVariant;
      arrData: Variant;
      RowCount, ColCount, i, j: Integer;
    begin
      {create variant array where we'll copy our data}
      RowCount := StringGrid1.RowCount;
      ColCount := StringGrid1.ColCount;
      arrData := VarArrayCreate([1, RowCount, 1, ColCount], varVariant);
    
      {fill array}
      for i := 1 to RowCount do
        for j := 1 to ColCount do
          arrData[i, j] := StringGrid1.Cells[j-1, i-1];
    
      {initialize an instance of Excel}
      xls := CreateOLEObject('Excel.Application');
    
      {create workbook}
      wb := xls.Workbooks.Add;
    
      {retrieve a range where data must be placed}
      Range := wb.WorkSheets[1].Range[wb.WorkSheets[1].Cells[1, 1],
                                      wb.WorkSheets[1].Cells[RowCount, ColCount]];
    
      {copy data from allocated variant array}
      Range.Value := arrData;
    
      {show Excel with our data}
      xls.Visible := True;
    end;
    
    0 讨论(0)
  • 2020-12-06 08:05
    procedure WriteToExcel();
    var
      txt : TextFile;
      Str : string;
      i : integer;
    begin
      try
        SaveDialog1.FileName := 'excelFile('+FormatDateTime('yyyy-dd-mm hh-nn-ss' ,(Now))+')';
        if SaveDialog1.Execute then
          begin
            AssignFile(txt, SaveDialog1.FileName+'.csv');
            try
              if FileExists(SaveDialog1.FileName) then
                Append(txt)
              else
                ReWrite(txt);
              Str := 'title1, title2, title3, title4, title5';
              WriteLn(txt, Str);
              ShowQuery.First();
              for i:=1 to StringGrid1.RowCount do
                begin
                  Str := StringGrid1.Cols[i][1] + ',';
                  Str := Str + StringGrid1.Cols[i][2] + ',';
                  Str := Str + StringGrid1.Cols[i][3] + ',';
                  Str := Str + StringGrid1.Cols[i][4] + ',';
                  Str := Str + StringGrid1.Cols[i][5];
                  WriteLn(txt,  Str);
                end;
            finally
              CloseFile(txt);
            end;
          end;
      except
    
      end;
    end;
    
    0 讨论(0)
提交回复
热议问题