Экспорт большого объёма данных (> 2Гб)

отредактировано 19:22 Раздел: FastReport 4.0
Здравствуйте.
Настал момент, когда заказчик захотел выгрузить огромный объём данных (порядка 3х млн. записей) в файл (в PDF).
Проблема заключается в том, что когда по такому объёму данных начинает строиться FastReport-отчёт - приложению банально не хватает памяти - упираемся в потолок для 32х битного приложения 2Гб.
Сами данные после выборки (если их выбрать все) занимают чуть меньше 1Гб, а когда по ним начинает строиться отчёт - каждая запись "обрастает" объектами типа TfrxMemo и память заканчивается мгновенно.

Допустим, мы загрзимся с опцией /3Gb в boot.ini. Допустим мы не будем выбирать все данные из БД на клиент (пусть курсор будет однонаправленный - данные будут выбираться порциями). Возможно памяти хватит, чтобы построить отчёт. Но его ещё нужно выгрузить (экспортировать в PDF).

Выпустить 64х-сборку приложения сейчас нет возможности (это новая версия Delphi, которую надо покупать - это планируется, но ещё не скоро это произойдёт, а потом ещё адаптация исходников - тоже неизвестно на какое время). А PDF-файл (ну или файлы) заказчик хочет уже сейчас.


Первое, что приходит в голову - это сделать экспорт в несколько файлов по какому-нибудь критерию (например тупо по количеству страниц) - заказчик на это соглашается. Однако хочется это сделать внутри самого скрипта отчёта.
Я начал "пробрасывать" в скриптовую систему функции, которые бы могли "по-тихому" экспортировать построенный отчёт в выбранный формат. Но я пока не понимаю, как экспортировать отчёт не после его построения, а экспортировать порциями в процессе построения.
Т.е. я хочу, чтобы: отчёт построился на N-страниц, затем произошёл экспорт в файл, затем очищаем отчёт (чтобы освободить память, иначе может настать момент, когда и /3Gb не хватит), затем строим следующие N-страниц и делаем экспорт, и так далее, пока приходят данные из БД.

Вопрос:
Есть ли готовые решения, или может быть кто-нибудь сталкивался с подобной задачей?
Повторюсь, хотелось бы реализовать это всё средствами скриптовой части самого отчёта - это было бы прозрачно для разработчика отчёта и понятно для пользователя.
В крайнем случае, можно запустить формирование отчёта в неком обработчике, который бы контролировал процесс построения и делал бы экспорт каждые N-страниц, но такой вариант (хоть он и проще в реализации) мне не нравится впринципе.

Комментарии

  • отредактировано 19:22
    Прокинуть в скрипт TfrxPDFExport и метод TfrxReport.Export оказалось проще простого и это работает.
    Например в обработчике (в скрипте отчёта) TfrxReport.OnStopReport я теперь могу написать что-то типа такого:
      procedure frxReportOnStopReport(Sender: TfrxComponent);
      var
        Filter: TfrxPDFExport;      
      begin
          Filter := TfrxPDFExport.Create(nil);
          try
            Filter.FileName := Format('D:\Temp\1\%d%s', [FilesCounter, '.pdf']);
            Filter.ShowDialog := False;                                                        
            Report.Export(Filter);
          finally
            Filter.Free;                                         
          end;
          FilesCounter := FilesCounter + 1;                                  
      end;
    
    и экспорт отрабатывает после построения отчёта.

    Впринципе, экспорт работает вообще в любой момент времени, даже в процессе построения - например в обработчике AfterPrint какого-нибудь объекта.
    Однако попытки удалить уже построенные (и экспортрованные) PreviewPages приводят к разного рода AccessViolation'ам :)
    Вот это для меня сейчас проблемно - корректно скзать типа ReportStop, потом очистить страницы, и сказать ReportStart (но не с начала, а как бы продолжить построение).

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

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