将VirtualStringTree导出为ex​​cel,csv?

是否可以将VirtualStringTree导出到Excel或CSV?

我正在使用Delphi 2007,并试图将我的VirtualStringTree数据logging保存为Excel或CSV格式。

我们有一个ExcelWriter助手类,可以转储各种东西到Excel,例如

  • TADOQuery
  • TListView的
  • TVirtualStringTree

在这种情况下,快速的方法(并且容易复制 – 在这里粘贴)是可以将variables数组转储到Excel的重载:

 class function TExcelWriter.ExportToExcelVariantArray(const VArray: Variant; const Title, SubTitle: WideString): Boolean; var xl: OleVariant; workbook: OleVariant; worksheet: OleVariant; range: OleVariant; Rowcount, ColumnCount: Integer; HeaderRowIndex: Integer; s: WideString; begin Result := False; if not VarIsArray(VArray) then raise EExcelWriterException.Create('ExportToExcelVariantArray: Supplied variant is not an array'); if VarArrayDimCount(VArray) <> 2 then raise EExcelWriterException.Create('ExportToExcelEVariantArray: Supplied variant array does not have 2 dimensions ('+IntToStr(VarArrayDimCount(VArray))+')'); ColumnCount := VarArrayHighBound(VArray, 2) - VarArrayLowBound(VArray, 2); //2 for "leftmost dimension" rowCount := VarArrayHighBound(VArray, 1) - VarArrayLowBound(VArray, 1); //1 for "leftmost dimension" try xl := CreateOleObject('Excel.Application'); except on E:Exception do begin if (E is EOleSysError) then begin if EOleSysError(E).ErrorCode = CO_E_CLASSSTRING then raise EExcelWriterException.Create('Excel is not installed.'+CRLF+ 'Could not load "Excel.Application" object (Co_E_CLASSSTRING)') else raise; end else raise; end; end; try xl.ScreenUpdating := False; xl.DisplayAlerts := False; // Don't display dialogs such as "save changes to workbook". workbook := xl.Workbooks.Add; try Worksheet := Workbook.Worksheets[1]; try Worksheet.Activate; Worksheet.Cells.WrapText := False; HeaderRowIndex := 1; //Rows&Columns in Excel start at one. range := TExcelWriter.GetRange(worksheet, HeaderRowIndex, 1, HeaderRowIndex+RowCount, ColumnCount); range.Value := VArray; //Bold the header row Worksheet.Rows[HeaderRowIndex].Font.Bold := True; Worksheet.Rows[HeaderRowIndex].Font.Underline := True; Worksheet.Columns.AutoFit; //Set printed header&footer if Copy(Title, 1, 2) = '@@' then s := Copy(Title, 3, MaxInt) else s := Title; if SubTitle <> '' then begin if s <> '' then s := s+#13; s := s + SubTitle; end; TExcelWriter.SetHeaderAndFooters(Worksheet, s, '', '', '&D &T', '', 'Page &P of &N'); finally Worksheet := Unassigned; end; finally Workbook := Unassigned; end; //When all done xl.ScreenUpdating := True; xl.Visible := True; xl.UserControl := True; // Very important, prevents Excel from going // away when we nil out our reference to it below. finally xl := Unassigned; end; Result := True; end; 

我们有一个TVirtualListView后裔,可以很容易地转换到VirtualTrees(它有TVirtualListItem等)。 然后它有一个帮助器方法ContentToVariantArray ,它类似于ContentToHtmlContentToRtf

 function TVirtualListView.ContentToVariantArray: Variant; var Columns: TColumnsArray; VArray: Variant; Node: PVirtualNode; ColumnCount: Integer; RowCount: Integer; nRow: Integer; i: Integer; begin Columns := Self.Columns.GetVisibleColumns; ColumnCount := Length(Columns); RowCount := Self.Items.Count+1; //+1 for the heaader VArray := VarArrayCreate([0, RowCount-1, 0, ColumnCount-1], varOleStr); //Docs say cannot use varString, must be varOleStr (which is a BSTR ie WideString) nRow := 0; for i := 0 to ColumnCount-1 do begin VArray[nRow, i] := Self.Columns.Items[Columns[i].Index].Text; end; Node := Self.GetFirst; while Assigned(Node) do begin Inc(nRow); for i := 0 to ColumnCount-1 do begin VArray[nRow, i] := Self.Text[Node, Columns[i].Index]; end; Node := Self.GetNextSibling(Node); end; Result := VArray; end; 

这里主要的缺点是我们正在自动化Excel以便使用它。 这意味着您的客户/服务器将需要安装Excel。

上面的代码显示了用户的Excel(不得不将文件保存到硬盘上,只是看它是浪费),而不是创build一个导出文件。 但不会很难调用.Save或API是什么。

CSV会更容易。

您的数据是您自己的数据,因为VirtualStringTree不包含数据,它是一个虚拟容器。 所以,如果你的虚拟string树是一个TMyObjects列表(容器)的视图,输出到CSV应该是相当简单的,而且虚拟树的内容只有在列的顺序不同可见的一组列被完成。

我build议你调查免费的JVCL JvCsvDataSet这是一个非常简单的方法来编写CSV文件。

如果你真的想要XLS输出,那么有库。

编写CSV文件(与html相同):

 var ss : AnsiString; ... if ExtractFileExt(DestFileName)='.htm' then ss:=VST.ContentToHtml(tstAll, 'Html exp') else ss:=VST.ContentToText(tstAll, ';'); with TFileStream.Create(DestFileName, fmCreate or fmShareDenyWrite) do begin Write(ss[1], length(ss)); Free; end;