LLLit: Изучение и практика программирования

Экспортировать VirtualStringTree в Excel, csv?

Можно ли экспортировать VirtualStringTree в Excel или CSV?

Я использую Delphi 2007 и пытаюсь сохранить свои записи данных VirtualStringTree в формате Excel или CSV.


  • В случае поддержки xls какие есть варианты (бесплатные)? Есть ли оболочка ADO, которую можно использовать (я думаю, есть импорт xls через ADO - как насчет экспорта). Моя компания планирует перейти с CSV на поддержку XLS 22.03.2011

Ответы:


1

У нас есть вспомогательный класс ExcelWriter, который может выгружать все виды данных в Excel, например.

  • ТАДОЗапрос
  • TListView
  • TVVirtualStringДерево

В этом случае быстрый способ (и простой для копирования и вставки здесь) — это перегрузка, которая может выгружать массив вариантов в 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 потомок TVirtualStringTree, который упростил переход на VirtualTrees (у него TVirtualListItem и т. д.). Затем у него есть вспомогательный метод ContentToVariantArray, который похож на ContentToHtml и ContentToRtf:

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 i.e. 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 (необходимость сохранять файл на жесткий диск только для того, чтобы просмотреть его расточительно), а не создание файла экспорта. Но было бы несложно вызвать .Save или какой-либо другой API.

13.06.2011

2

CSV было бы проще.

Ваши данные — это ваши собственные данные, поскольку VirtualStringTree не содержит данных, это виртуальный контейнер. Таким образом, если ваше виртуальное строковое дерево является представлением списка TMyObjects (контейнера), его вывод в CSV должен быть относительно тривиальным, и содержимое виртуального дерева будет действительно иметь значение только в том случае, если ваши столбцы могут быть в другом порядке или набор видимых столбцов выполнен.

Я предлагаю вам изучить бесплатный JVCL JvCsvDataSet, который является действительно простым способом записи файлов CSV.

Если вам действительно нужен вывод XLS, для этого есть библиотеки.

10.02.2010
  • TJvCsvDataSet находится в наборе компонентов JVCL: sourceforge.net/projects/jvcl/files 10.02.2010

  • 3

    Написание 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;
    
    14.11.2013
  • В Delphi 10.4 используйте тип String. 20.09.2020
  • Новые материалы

    Как развивается смешанно-целочисленное программирование, часть 7
    Унифицированная техника раннего завершения для первично-двойственных алгоритмов в смешанно-целочисленном коническом программировании (arXiv) Автор : Ювэнь Чэнь , Кэтрин Нин , Поль Гулар..

    Как научить модель Keras распознавать текст переменной длины
    Я некоторое время играл с официальным примером Keras image_ocr.py и хочу поделиться своими выводами в этом посте. В официальном примере выполняется только обучение модели, но отсутствует..

    Практическая пакетная нормализация
    История начинается после использования инициализации He вместе с ELU (или любым вариантом ReLU) может значительно снизить опасность проблем с исчезающими/взрывающимися градиентами в начале..

    Поэзия онлайн-кодирования: путешествие пикселей и страсти
    В мире, наполненном инновациями, онлайн-обучение программированию становится холстом, на котором обретает форму полотно вашей мечты. Это больше, чем просто создание строк кода; это сродни..

    Обработка изображений с помощью Python - размытие и повышение резкости для начинающих
    Как применить ядра свертки к цветным изображениям? В этой статье мы обсудим, как применять ядра размытия и повышения резкости к изображениям. Эти базовые ядра составляют основу многих более..

    Ограничение скорости в .NET Core 7 Web API
    Что такое ограничение скорости? Ограничение скорости — это процесс, используемый для ограничения количества запросов, разрешенных для определенного ресурса в указанном временном окне. .NET..

    Стабильная Diffusion 1.0 выдаёт более красивые картинки, чем SD 2.1?! Почему?
    Удивительные открытия, которые я сделал недавно. Смотрите в видео: https://youtu.be/PakgD6FewoU Есть одно логичное объяснение — что у вас?