Когда задача стоит “Сохранить из Delphi или Lazarus в Excel” у разработчика просто огромный выбор - частично он описан в статье “Как записать в XLS Biff8 из Delphi”, там же я вкратце расписал, почему это плохой выбор. А что же тогда хорошо? А хорошо - сохранять в новый (ну, относительно новый) XML XLSX.
"XML является технологией, разработанной для управления структурированными данными и отображения этих данных в виде удобочитаемого текстового файла. Язык XML соответствует отраслевым стандартам и может быть обработан многими базами данных и приложениями. С помощью XML многие разработчики могут создавать собственные настроенные теги, структуры данных и схемы. В целом XML существенно облегчает определение, передачу, проверку и интерпретацию данных в различных базах данных, приложениях и организациях. "
Но Microsoft не был бы собой, если бы, традиционно не попытался сделать “свой собственный XML - c блэкджеком и ячейками!”. А потому у Excel на самом деле есть не один а целых два(!) XML-стандарта для хранения Excel-файлов: более ранний и более правильный.
Как я уже неоднократно указывал, FastReport позволяет сохранять из Delphi и Lazarus ваши документы, отчёты информацию в великое множество форматов. Сделать сам отчёт - легче лёгкого, можно посмотреть в прошлых статьях - единственное, опять остановлюсь-отмечу - следите за выравниванием ваших объектов, чтобы результирующие табличные форматы получались красивыми качественными! Так вот - для Excel XML у нас два разных(!) фильтра экспорта. Вот, полюбуйтесь!
Видим окно предварительного просмотра и кнопку “сохранить”
“Эй, уважаемый, а мне, простому программисту чем пользоваться?!” - спросите вы и будете совершенно правы. Короткий ответ - 2007 XML, более поздний. А ниже я расскажу, почему.
Понятно, что программист никогда не делает “потому, что захотелось” - хочется чего-либо пользователю. В чём же разница в этих двух форматах с точки зрения пользователя, жаждущего получить таблицу Excel из приложения? Со стороны пользователя разница примерно как между rft без картинок и полноценным файлом MS Word, и первый в реальной жизни почти не встречается. В простом XML нет, ни стилей ни картинок. Просто таблица в XML. Но в момент, когда его придумывали, и выбора-то особо не было - это был огромный шаг вперёд для MS Excel. А вот Microsoft Excel 2007 XML может хранить картинки , там есть стили и тд. Это контейнер OOML.
Углубиться в тему XML используемого с 2007 и далее можно тут - там целый мир!
А мы просто сравним два варианта сохранения в XML и XLSX XML и решим, какой использовать рациональнее и в каких случаях.
Экспорт в XML - более простой. Экспортируются только текстовые объекты. Изображения, графики, карты, штрихкоды, форматирование TfrxRichView, HTML-тэги и фоновое изображение в результирующий Excel XML не попадут.
Ниже традиционно распишу, как реализовать сохранение в Excel XML полностью из кода, если не хочется или не требуется показывать предпросмотр и давать возможность отправить на печать. Окошко настроек экспорта в XML . Специально размещаю рядом для сравнения настройки. Всё не просто, а очень просто!
Средства FastReport помогают выбрать, какие страницы нашего документа отправить в Excel, диапазон или только определённые страницы.
Настройки экспорта – большее визуальное соответствие с начальным вариантом (WYSIWYG), разрыв страницы, и continuous - непрерывный документ с пропуском промежуточных заголовков и подвалов страниц.
Как будет выглядеть результат: без разделения, разделение на листы с использованием страниц отчёта, Use print on parent - каждой странице TfrxReportPage в шаблоне отчёта соответствует лист книги (при условии, что TfrxReportPage.PrintOnParent = False) или же поделить на части с задаваемым количеством строк.
Открыть после экспорта – результирующий файл будет открыт сразу же после экспорта программой Microsoft Excel (Ну или что у пользователя в системе ассоциировано с файлами расширения XLSX для их открытия).
Получившийся XML\ XLSX можно сохранить в виде файла с расширением .xml в памяти компьютера, отправить на FTP, отправить по Email или загрузить в одно из облачных хранилищ (Dropbox, OneDrive, Box.com, GoogleDrive).
Первый скриншот - это результат сохранения в формате XLSX и как мы видим, данный формат не поддерживает данные сложнее обычного текста. А вот второй скриншот показывает нам все возможности формата XML, т.е. полную поддержку штрихкодов, картинок. Если говорить про вес файлов, то результат ожидаемый: XLSX 48,0 КБ, XML 40,0 КБ.
Разберёмся подробнее почему XLSX весит больше XML. За основу взяли вот этих прекрасных рыбок. Данный документ содержит много текста, табличные данные и 30 фотографий. Для большей наглядности сравним ещё и нестареющий Excel 97, о котором мы говорили в другой статье.
Excel 97 - Формат двоичных файлов, бинарник (biff8), про сжатие тут не слышали и потому вес файла столь велик. В отличии от более позднего XML, формат 97 года поддерживает все виды изображений.
Excel table (XML) - Ранняя версия XLSX, где данные хранятся как простые одиночные монолитные XML-файлы, что делает их довольно большими, по сравнению с OOXML и устаревшими двоичными форматами Microsoft Office. Но на скриншоте вес минимален - возмутился бы каждый! Ответ прост, данный вес указан за документ, где отображаться будет только текст. А теперь представьте, если бы тут всё-таки была поддержка картинок, да он бы занимал кучу места, ведь о сжатии на этом моменте всё ещё никто не знает. Кроме того, встроенные элементы, такие как изображения, хранятся в виде двоичных закодированных блоков, но недоступны для отображения.
Excel 2007 XLSX (XML) - Microsoft взяли лучшее от прошлых форматов и внедрили сжатие файлов. Размер документа приблизительно на 50-75 процентов меньше, чем в предыдущих версиях.
Количество столбцов увеличилось с 256 до 16 384, количество строк в листе возросло с 65 536 до 1 048 576. Ускорены вычисления в больших листах, содержащих множество формул, благодаря поддержке Office Excel 2007 нескольких процессоров и многопоточных наборов микросхем.
Пример кода записи в XLSX XML с настройками | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
procedure TForm1.Button1Click(Sender: TObject); begin {Формируем отчёт. Перед экспортом отчёт необходимо обязательно сформировать} frxReport1.PrepareReport(); {Устанавливаем диапазон экспортируемых страниц. По умолчанию экспортируются все страницы сформированного отчёта} frxXMLExport1.PageNumbers := '2-3'; {Устанавливаем, нужно ли формировать непрерывный документ с пропуском промежуточных заголовков и подвалов страниц. Включение этой опции отключает TfrxXMLExport.ExportPageBreaks} frxXMLExport1.SuppressPageHeadersFooters := True; {Устанавливаем, экспортировать ли разрывы страниц в пределах листа книги, чтобы страницы при печати соответствовали страницам сформированного отчёта} frxXMLExport1.ExportPageBreaks := True; {Устанавливаем WYSIWYG} frxXMLExport1.Wysiwyg := True; {Устанавливаем порядок разбивки документа, используя свойство Split, которое может принимать следующие значения: ssNotSplit - создаётся непрерывный документ; ssRPages - каждому листу сформированного отчёта соответствует лист книги; ssPrintOnPrev - каждой странице TfrxReportPage в шаблоне отчёта соответствует лист книги (при условии, что TfrxReportPage.PrintOnParent = False); ssRowsCount - на каждом листе будет заданное в свойстве TfrxXMLExport.RowsCount количество строк.} frxXMLExport1.Split := ssNotSplit; {Устанавливаем, нужно ли открывать результирующий файл после экспорта} frxXMLExport1.OpenAfterExport := False; {Устанавливаем, нужно ли отображать прогресс экспорта (показывать, какая страница в данный момент экспортируется)} frxXMLExport1.ShowProgress := False; {Устанавливаем, нужно ли отображать окно диалога с настройками фильтра экспорта} frxXMLExport1.ShowDialog := False; {Устанавливаем имя результирующего файла.} {Обратите внимание на то, что если не установить имя файла и отключить показ диалогового окна фильтра экспорта,} {то всё равно будет отображён диалог выбора имени файла} frxXMLExport1.FileName := 'C:\Output\test.xls'; {Экспортируем отчёт} frxReport1.Export(frxXMLExport1); end; |
Экспорт из кода в XLSX Excel 2007 с настройками | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
procedure TForm1.Button2Click(Sender: TObject); begin {Формируем отчёт. Перед экспортом отчёт необходимо обязательно сформировать} frxReport1.PrepareReport(); {Устанавливаем диапазон экспортируемых страниц. По умолчанию экспортируются все страницы сформированного отчёта} frxXLSXExport1.PageNumbers := '2-3'; {Устанавливаем, нужно ли формировать непрерывный документ с пропуском пустых линий, промежуточных заголовков и подвалов страниц (при EmptyLines = False). При EmptyLines = True отчёт экспортируется в том виде, в котором он сформирован. Без пропуска пустых линий, промежуточных заголовков и подвалов страниц. Включение этой опции отключает TfrxXLSXExport.SuppressPageHeadersFooters и наоборот} frxXLSXExport1.EmptyLines := True; {Устанавливаем, экспортировать ли разрывы страниц в пределах листа книги, чтобы страницы при печати соответствовали страницам сформированного отчёта} frxXLSXExport1.ExportPageBreaks := True; {Устанавливаем WYSIWYG} frxXLSXExport1.Wysiwyg := True; {Устанавливаем, нужно ли экспортировать только содержимое дата-бэндов} frxXLSXExport1.DataOnly := False; {Устанавливаем порядок разбивки документа: при установленной опции SingleSheet все страницы документа будут расположены на одном листе frxXLSXExport1.SingleSheet := True; Если установить значение ChunkSize, то на каждом листе будет заданное количество строк. SingleSheet в этом случае должно быть False frxXLSXExport1.ChunkSize := 50; Мы установим порядок, когда каждому листу сформированного отчёта соответствует лист книги} frxXLSXExport1.SingleSheet := False; frxXLSXExport1.ChunkSize := 0; {Устанавливаем, нужно ли открывать результирующий файл после экспорта} frxXLSXExport1.OpenAfterExport := False; {Устанавливаем, нужно ли отображать прогресс экспорта (показывать, какая страница в данный момент экспортируется)} frxXLSXExport1.ShowProgress := False; {Устанавливаем, нужно ли отображать окно диалога с настройками фильтра экспорта} frxXLSXExport1.ShowDialog := False; {Устанавливаем имя результирующего файла. Обратите внимание на то, что если не} {установить имя файла и отключить показ диалогового окна фильтра экспорта,} {то всё равно будет отображён диалог выбора имени файла} frxXLSXExport1.FileName := 'C:\Output\test.xlsx'; {Экспортируем отчёт} frxReport1.Export(frxXLSXExport1); end; |
Теперь мы знаем, как из Delphi и Lazarus записать в XLSX и в XML Excel 2007 (и выше) - и какой из этих форматов лучше выбирать!