工作中处理报表,弃 dxDBGrid cxGrid,直接以 ListView 显示数据结果,而后需将报表数据保存为 Excel(或 Word)文件,本窃喜 TMS 套件里的 AdvListView SavetoXLS(filename: string; SaveWithHTML: boolean = true) 等方法,但试后却较失望 如此方法,将数据存入 Excel 时只保存 ListView 内容,却没将 ListView 列头写入 Excel——有躯干没脑袋,不完整的说
索性参考其源码,自己动手

uses
  ComObj, Variant;

procedure SaveLVToXLS(LV: TListView;  FileName: string);
var
  aExcel: Variant;
  aWorkBook: Variant;
  aWorkSheet: Variant;
  Ary: Variant;
  i, j: Integer;
  RangeStr: string[12];
  aLstItem: TListItem;
  cells: string;
begin
  try
    aExcel:= CreateOleObject('Excel.Application');
  except
    on E: Exception do
    begin
      MessageBox(
                              Handle,  
                              PChar('导出报表失败!' + #13 + '失败原因:' + E.Message + ' '),
                              '错误',
                              MB_OK + MB_ICONERROR
                             );
      Exit;          
    end;
  end;

  aWorkBook:= aExcel.WorkBooks.Add;
  aWorkSheet:= aWorkBook.WorkSheets.Add;

  Ary:= VarArrayCreate([0, LV.Items.Count, 0, LV.Columns.Count], varVariant);

  for j:= 0 to LV.Columns.Count - 1 do //暂存 ListView 之列头
  begin
    cells:= LV.Columns[j].Caption;
    Ary[0, j]:= cells;
  end;

  for i:= 1 to LV.Items.Count do //暂存 ListView 之内容
  begin
    aLstItem:= LV.Items;
    for j:= 0 to LV.Columns.Count - 1 do
    begin
      if j = 0 then
        cells:= aLstItem.Caption
      else
      begin
        if j - 1 >= aLstItem.SubItems.Count then
          cells:= ''
        else
          cells:= aLstItem.SubItems[j - 1];
      end;
      Ary:= cells;
    end;
  end;

  RangeStr:= 'A1:';
  if (LV.Columns.Count > 26) then
  begin
    RangeStr:= RangeStr + Chr(Ord('A') - 1 + (LV.Columns.Count div 26));
    RangeStr:= RangeStr + Chr(Ord('A') - 1 + (LV.Columns.Count mod 26));
  end
  else
    RangeStr:= RangeStr + Chr(Ord('A') - 1 + LV.Columns.Count);

  RangeStr:= RangeStr + IntToStr(LV.Items.Count + 1);
  aWorkSheet.Range[RangeStr].Value:= Ary;
  aWorkbook.SaveAs(FileName);

  aExcel.Quit;
  aExcel:= UnAssigned;
end;

参数说明:
LV:要导出数据的 ListView 名;FileName:目标文件名(如 MyRpt.XLS)。

可完善之如,设定 Excel Cell 的宽度;也可再封装一个带数据导出功能的 TListView,若有必要或感兴趣。

P.S: TMS 怎就不能将其方法稍加改造,让用户选择是否导出 ListView 的列头呢?不过多一个参数而已...