Delphi excel сохранить как

Обновлено: 05.07.2024

Когда вы первый раз заходите с помощью соцсетей, мы получаем публичную информацию из вашей учетной записи, предоставляемой провайдером услуги соцсети в рамках ваших настроек конфиденциальности. Мы также автоматически получаем ваш e-mail адрес для создания вашей учетной записи на нашем веб сайте. Когда она будет создана, вы будете авторизованы под этой учетной записью. Когда вы первый раз заходите с помощью соцсетей, мы получаем публичную информацию из вашей учетной записи, предоставляемой провайдером услуги соцсети в рамках ваших настроек конфиденциальности. Мы также автоматически получаем ваш e-mail адрес для создания вашей учетной записи на нашем веб сайте. Когда она будет создана, вы будете авторизованы под этой учетной записью.

Очень хорошие статьи. Разобрался во всём с первого раза ))) Понравилась схема в mind42 )))
Автору остаётся сказать только спасибо!

не за что, Иван. Всегда рад помочь)

Странно. Если Excel запущен, то должна создаваться вторая копия приложения без исключений. Код в студию :)

Насчет процедуры CheckExcelRun. Если программа запускается из под Delphi и Excel не запущен, то выскакивает ошибка: Операция GetActiveOleObject недоступна. Если програма запускается не из под Delphi то все в порядке. Наверное эту проблему имел ввиду Алекс. Как решение можно при отладке программы когда возникает исключение нажимать F9.

По сабжу пока не работал, но скорее всего либо перменная FileName уже объявлена, либо тип TFileName из модуля SysUtils, где-то переопределен.

Помогите Вопрос! Я использую шаблоны в своей программе! Можно ли из Дельфи изменть путь Save as. Что бы при слхранений пользавателем путь сохранения был изменен? Спасибо

А можно ли проверить, что не просто запущен Excel, а уже имеется открытая конкретная книга.
Например, хочу создать в Excel (усли уже создана, то открыть) книгу table.xls

Канает в любой версии Delphi, даже в XE.

begin
result:=CheckExcelRun;
if not result then
if AutoRun then
begin
RunExcel;
result:=CheckExcelRun;
end;
if result then MyExcel.WorkBooks.Add;
end;

Или так :-)
begin
result:=CheckExcelRun;
if (not result) and (AutoRun) then
begin
RunExcel;
result:=CheckExcelRun;
end;
if result then MyExcel.WorkBooks.Add;
end;

Ну так отладчик же понятно говорит, что переменная Rez повторно объявлена. Ищите где повторное объявление. Может где в глобальных переменных повторились

function isExcelInstalled:boolean;
var
ClassID: TCLSID;
begin
Result := CLSIDFromProgID(PWideChar(WideString(ExcelApp)), ClassID) = S_OK;
end;

Понятнее и короче.

Народ , а нельзя вбить какую нить формулу в excel и чтобы результат вычисления выводился в проге в Дельфи? просто я только разбираюсь в дельфи и не знаю как это через дельфи сделать..

Это будет проще сделать в делфи, и на много облегчит программу.

MsExcel : Variant;
_Sheet : TStringList;
i, x : integer;
CCR_Ver, lLastRow, Name_Sheet, path : String;

MsExcel.Workbooks.Open[XLS_File.FileName, 0, True];

// видимость Excel
MsExcel.Visible := False;
// Закрытие открытой книги
MsExcel.WorkBooks[MsExcel.WorkBooks.Count].Close(false);
// Закрытие Excel
MsExcel.quit;
// Перераспределение памяти
inherited;
close; // Закрытие формы frm_CCR_mos
end;

Влад, здравствуйте.
Я могу с Вами как либо связаться и задать пару вопросов?

GS, спасибо большое. Не возражаете, если я, по мере наличия свободного времени, опубликую в блоге отдельным постом эти примеры (Естественно с указанием настоящего автора примеров). Думаю, что такой пост может пригодиться многим.

GS! Подскажите, где взять библиотеку XLSReadWrite?

Буду только рад :)

Ребят, вы даже представить себе не можете, насколько это полезная информация)))
Спасибо!

подскажите плиз как сделать следующее с помощью компонентов XLSReadWrite
1. открыть книгу
2. сделать поиск построчно в столбце например T при этом нужен поиск с частичным совпадением текста.
3. организовать поиск по многим книгам за 1 проход.

текущий пример как сделано сейчас прилагаю. Открытие книги и поиск в ней выполняются за 9 секунд в среднем в двух книгах за 18. хотелось бы уменьшить данное время на сколько это возможно.

заранее спасибо всем откликнувшимся.

Вопрос поднимался выше, не ответили:
Не компилит функция Save, «FileName:TFileName», пишет:
1. если не определяем параметры функции SaveWorkSheet, пишет что не хватает актуальных параметров
2. ставлю параметры, (индекс), пишет что не соответствие типов String/Integer,

Vlad огромное спасибо за статью
Просьба есть: нельзя ли перезалить модуль.. как тут уже писали он не скачивается по ссылке :(

При объявлении переменой типа OleVariant, у самой переменой нету никаких методов/классов. После нажатия точки вылазит только (*,

Хотя сами методы компилятор видит. WorkBooks, Sheet, Range, Cells и т.п.

Именно так и должно быть, т.к. мы используем раннее связывание.

кто-то может передать экземпляр сломанной ссылке

подскажите пож как сделать чтобы когда вбиваешь edit текс он выводился в excel и когда я водил опять он спускался на строчку ниже а не -заменял преждний

В прошлой статье (Читаем файл Excel (xls) в Delphi) был рассмотрен способ чтения данных из xls файла и его импорт в Delphi. Теперь перейдем к сохранению, т.е. к экспорту данных из Delphi. Экспорт, как и импорт, будет осуществляться через посредника, т.е. Excel. Поэтому для работы приложения потребуется установленная копия MS Excel 2003-2010 (выше не тестировал).

Добавьте на форму кнопку, диалог сохранения, и таблицу StringGrid. Для того чтоб появилась возможность редактирования таблицы StringGrid необходимо в ее свойствах включить опцию goEditing:


Визуальные приготовления для нашего примера готовы. Переходим к написанию кода.

Как и в случае чтения xls нам понадобится библиотека ComObj. Добавьте ее в uses. Ниже приведен листинг процедуры экспорта, добавьте его после ключевого слова implementation.

procedure Xls_Save(XLSFile:string; Grid:TStringGrid);
const
xlExcel9795 = $0000002B;
xlExcel8 = 56;
var
ExlApp, Sheet: OLEVariant;
i, j, r, c:integer;

begin
//создаем объект Excel
ExlApp := CreateOleObject('Excel.Application');

//делаем окно Excel невидимым
ExlApp.Visible := false;

//создаем книгу для экспорта
ExlApp.Workbooks.Add;

//создаем объект Sheet(страница) и указываем номер листа (1)
//в книге, в который будем осуществлять экспорт
Sheet := ExlApp.Workbooks[1].WorkSheets[1];

//задаем имя листу
Sheet.name:='Данные_из_Delphi';

//считываем кол-во столбцов и строк в StringGrid
r:=Grid.RowCount;
c:=Grid.ColCount;

//считываем значение из каждой ячейки и отправляем в таблицу Excel
for j:= 1 to r do
for i:= 1 to c do
sheet.cells[j,i]:=Grid.Cells[i-1,j-1];

//отключаем все предупреждения Excel
ExlApp.DisplayAlerts := False;

//обработка исключения при сохраннении файла
try
//формат xls 97-2003 если установлен 2003 Excel
ExlApp.Workbooks[1].saveas(XLSFile, xlExcel9795);
showmessage('Файл сохранил 2003-ий офис');
except
//формат xls 97-2003 если установлен 2007-2010 Excel
ExlApp.Workbooks[1].saveas(XLSFile, xlExcel8);
showmessage('Файл сохранил 2007 или 2010-ый офис');
end;

//закрываем приложение Excel
ExlApp.Quit;

//очищаем выделенную память
ExlApp := Unassigned;
Sheet := Unassigned;

end;

Алгоритм работы процедуры:

Вот и все. С полным листингом проекта Вы можете ознакомиться, скачав приложенный ниже архив. Так же в архиве содержится список констант типов, позволяющий по желанию расширить список экспортируемых типов доступных Excel.

При написании бизнес приложений на Delphi, выполняющих какие либо расчеты, может возникнуть необходимость импорта (экспорта) данных из файлов других приложений. Одно из основных таких приложений – MS Excel. Как прочитать файлы xls в Delphi мы сейчас и рассмотрим!?

Создадим новый проект и разместим на форме три компонента:

StringGrid – находится на палитре компонентов, во вкладке Additional

stringgrid в delphi

Кнопку Button и для удобства выбора файлов, диалог открытия файлов (работа с диалогами описана здесь).

Для StringGrid, в свойствах(Properties) укажем следующее:
DefaultRowHeight – 17
FixedCols – 0
FixedRows – 0

В результате форма будет выглядеть примерно так:


На этом украшательства закончим и приступим к написанию кода.

Для работы с Excel файлами нам понадобится библиотека ComObj, входящая в стандартную поставку Delphi. Подключается она в разделе Uses. Добавьте в конце, после запятой «ComObj».


Теперь опишите процедуру Xls_Open после ключевого слова implementation:

procedure Xls_Open(XLSFile:string; Grid:TStringGrid);
const
xlCellTypeLastCell = $0000000B;
var
ExlApp, Sheet: OLEVariant;
i, j, r, c:integer;

begin
//создаем объект Excel
ExlApp := CreateOleObject('Excel.Application');

//делаем окно Excel невидимым
ExlApp.Visible := false;

//открываем файл XLSFile
ExlApp.Workbooks.Open(XLSFile);

//создаем объект Sheet(страница) и указываем номер листа (1)
//в книге, с которого будем осуществлять чтение
Sheet := ExlApp.Workbooks[ExtractFileName(XLSFile)].WorkSheets[1];

//активируем последнюю ячейку на листе
Sheet.Cells.SpecialCells(xlCellTypeLastCell, EmptyParam).Activate;

// Возвращает номер последней строки
r := ExlApp.ActiveCell.Row;

// Возвращает номер последнего столбца
c := ExlApp.ActiveCell.Column;

//устанавливаем кол-во столбцов и строк в StringGrid
Grid.RowCount:=r;
Grid.ColCount:=c;

//считываем значение из каждой ячейки и копируем в нашу таблицу
for j:= 1 to r do
for i:= 1 to c do
Grid.Cells[i-1,j-1]:= sheet.cells[j,i];
//если необходимо прочитать формулы то
//Grid.Cells[i-1,j-1]:= sheet.cells[j,i].formula;

//закрываем приложение Excel
ExlApp.Quit;

//очищаем выделенную память
ExlApp := Unassigned;
Sheet := Unassigned;

end;

Наша процедура Xls_Open имеет два входных параметра:

  1. XLSFile – путь к файлу Excel (xls)
  2. Grid – таблица, в которую будем осуществлять вывод данных.

В комментариях к коду я постарался все расписать, объясню немного принцип работы процедуры.

Мы создаем в памяти объект ExlApp с приложением Excel.Application. Затем указываем что этот объект будет невидим для пользователя ExlApp.Visible := false (если false заменить на true, то при открытии файла мы увидим окно Excel с открываемым файлом). Далее открывается файл ExlApp.Workbooks.Open(XLSFile). Потом создаем еще один объект Sheet, который позволяет работать с листом книги Excel: Sheet := ExlApp.Workbooks[ExtractFileName(XLSFile)].WorkSheets[1]. Единица в конце указывает номер листа с которого будем читать данные (к листам можно обращаться по имени, для этого вместо 1 указываем «ИмяЛиста1»). Далее определяем кол-во строк и столбцов которые содержат данные, и используя циклы For считываем данные копируя их в StringGrid. Впринципе и все.

Для использования процедуры Xls_Open пропишем в событие Click кнопки Button1 следующее:

If OpenDialog1.Execute then Xls_Open (OpenDialog1.FileName, StringGrid1);

Основные недостатки этого способа: медленное чтение данных (хотя для небольших файлов вполне сгодится) и необходимость установленной версии Excel на компьютере пользователя.

Полный листинг программы:

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Grids, StdCtrls,ComObj;

type
TForm1 = class(TForm)
StringGrid1: TStringGrid;
Button1: TButton;
OpenDialog1: TOpenDialog;
procedure Button1Click(Sender: TObject);
private

public

end;

var
Form1: TForm1;

implementation

procedure Xls_Open(XLSFile:string; Grid:TStringGrid);
const
xlCellTypeLastCell = $0000000B;
var
ExlApp, Sheet: OLEVariant;
i, j, r, c:integer;

begin
//создаем объект Excel
ExlApp := CreateOleObject('Excel.Application');

//делаем окно Excel невидимым
ExlApp.Visible := false;

//открываем файл XLSFile
ExlApp.Workbooks.Open(XLSFile);

//создаем объект Sheet(страница) и указываем номер листа (1)
//в книге, с которого будем осуществлять чтение
Sheet := ExlApp.Workbooks[ExtractFileName(XLSFile)].WorkSheets[1];

//активируем последнюю ячейку на листе
Sheet.Cells.SpecialCells(xlCellTypeLastCell, EmptyParam).Activate;

// Возвращает номер последней строки
r := ExlApp.ActiveCell.Row;

// Возвращает номер последнего столбца
c := ExlApp.ActiveCell.Column;

//устанавливаем кол-во столбцов и строк в StringGrid
Grid.RowCount:=r;
Grid.ColCount:=c;

//считываем значение из каждой ячейки и копируем в нашу таблицу
for j:= 1 to r do
for i:= 1 to c do
Grid.Cells[i-1,j-1]:= sheet.cells[j,i];
//если необходимо прочитать формулы то
//Grid.Cells[i-1,j-1]:= sheet.cells[j,i].formula;

//закрываем приложение Excel
ExlApp.Quit;

//очищаем выделенную память
ExlApp := Unassigned;
Sheet := Unassigned;

end;

procedure TForm1.Button1Click(Sender: TObject);
begin
If OpenDialog1.Execute then Xls_Open (OpenDialog1.FileName, StringGrid1);
end;

end.

Обновленный пример. Добавлена функция отбора строк по критерию. Так же добавлен обработчик делающий отображение шрифта "шапки" в StringGrid жирным. Все дополнения постарался по максимуму раскомментить


О, это вечная тема - сделать таблицу Эксель из Delphi.
Таблицы Excel – сегодня один из мировых стандартов. А для программ, даже простых, частое требование – это вывод данных в виде таблиц и перенос отчёта в таблицу. Сразу отмечу, что XLS формат уже устаревший, это внутренний формат Microsoft Excel под названием Biff8 (целый мир со своими взаимосвязями между, с первого взгляда, никак не связанными сущностями, ячейками, бесконечными вкладками и страницами с участками файла, записанного в хардкорном бинарном формате), тем не менее - есть компании, заказчики, у которых именно такое требование. Таких заказчиков хорошо бы сразу палкой по голове бить предупредить, что для реальных больших данных этот формат НЕ ГОДИТСЯ - сами полюбуйтесь :

"Excel has limits on the amount of data a cell can hold: for Excel BIFF 8 files, that limit is 32,767 characters, so (in theory) 200+ characters should not be an issue. However, for longer strings, this data is maintained in the BIFF file across several blocks with continuation records, For BIFF 5 files (Excel 95) the limit is 2084 bytes per block; in BIFF 8 files (Excel 97 and above) the limit is 8228 bytes. Records that are longer than these limits must be split up into CONTINUE blocks."

- там и число столбцов, и строк, и данных в них - ограничены. Лучше уж что-то новое использовать. В другой статье я расскажу, как сохранять из Delphi в XLSX XML (куда как более приятные форматы - хотя тоже Excel).

Но если уж захотелось странного, и недостатки формата вас не испугали, то пойдём пугаться дальше тут есть несколько возможностей:

  1. Вывод таблицы XLS прямо сразу из StringGrid через вызовы OLE / OLE-container - у этого способа есть несколько неприятных моментов - вам всенепременно нужен установленный Microsoft Excel на компьютере (мы же не пираты какие - обязательно купить лицензию надо!), разрядность системы, установленного пакета MS Office и вашей скомпилированной программы должны совпадать (вы даже не представляете, сколько незабываемых часов отладки может сам доставить, например, 32-битный офис на 64-битной системе!), ваша табличка должна быть небольшой (на больших данных OLE, работая непосредственно в оперативной памяти, сразу упадёт с громким треском, потянув за собою и Excel и вашу программку), и даже для этой маленькой программки у вас должно быть достаточно времени. Процесс передачи серийных данных через OLE медитативен и не терпит суеты. Запрос “delphi ole excel container save file” скрасит вам не один вечер.
  2. Окей, предположим, хочется делать всё по-взрослому - и отправлять в XLS большие объемы данных. Тогда приходят на помощь всевозможные библиотеки для записи сразу в XLS - например, TXLSFile. Есть и у этого подхода некоторые недостатки. Например - изображения, картинки, штрихкоды в ячейки поместить, да те же рамки-обрамления ячеек - не то чтобы невозможно, но будут результатом некоторых, скажем так, усилий.
  3. Или TMS FlexCel. Вы можете сделать отчёт в TMS FlexCel с картинкаи и совсем без программирования. Если же вы хотите сделать это из кода, у них есть инструмент для его генерации! *
  4. Так а что же делать? Выход, как обычно в этом блоге, есть - и это FastReport VCL! Во-первых, спокойно, используя максимум визуальных прелестей, делаете документ, отчёт (называйте, как хотите - хоть каталог для своих дилеров - и это не шутка, люди и не такое делают), потом экспортируйте готовый результат, как он есть - в Excel! Да, используйте рекомендации по подготовке отчёта - делайте его сразу ТАБЛИЧНЫМ, “аккуратненько, под линеечку” - FastReport, понятно, постарается наложенные друг на друга объекты вписать в таблицу - но так из пары объектов может получиться до 9(!) ячеек - вам же самим не понравится такой результат!

Записываем XLS из Delphi c помощью FastReport

Итак, ваш документ содержит большие таблицы, многоуровневые списки, иллюстрации, карты, штрих-коды и вы думаете, как бы это перенести в Excel?
Не буду тут повторно останавливаться на создании отчёта - бросили на форму проекта TfrxReport, TfrxBIFFExport и TButton, прописали на кнопку вызов

- строим отчёт и запускаем окно предпросмотра того, что получилось.
Видим окно предварительного просмотра и кнопку “сохранить”

Выбор сохранения Excel 97/2000/XP file.

И, в принципе, как будет выглядеть результат: разбивать на страницы, оставив в изначальном виде, расположить всё на одной странице или же поделить на части с задаваемым количеством строк.

Открыть после экспорта – результирующий файл будет открыт сразу же после экспорта программой Microsoft Excel.

служебная информация в XLS
Защита XLS biff8 паролем
дополнительные настройки XLS biff8

Служебная информация, которая также пойдёт в Excel-файл: название, автор, ключевые слова, версия документа, приложения, категория, менеджер и комментарий к файлу.

Безопасность — защита паролем документа (дополнительно можно указать подтверждение).

Если задать непустую строку пароля, то сгенерированный файл будет защищён паролем. Пароль пишется только символами Юникода и должен быть короче 256 символов.

Опции – настройка документа на большее визуальное соответствие с первоначальном вариантом (WYSIWYG), экспорт в таблицу картинок-изображений, отображения границ ячеек, выставлять размер страницы, удаление пустых строк (для экономии места в этом конкретном формате очень важная опция), экспорт формул.

Если не нужно столь подробно выставлять параметры, то можно оставить всё по умолчанию.

Отправка из Delphi / Lazarus в Excel(Biff8) из кода

Какие побочные эффекты у такого варианта создания Excel-листов из Delphi? Прежде всего, это на порядок быстрее и надёжнее, чем запись в XLS Biff8 через OLE-container (можете сами сравнить), да и возможности пошире (если, конечно, не нужно просто тупо выгнать StringGrid 100х100 в Excel, который гарантированно стоит на машинке без возможности обновлений), оно платформонезависимое (Linux-приложения, сделанные в Lazarus спокойно будут генерить XLS - и потом открыть в каком-нибудь Open Office / Libre Office), форматирование, свойства текста, цвета, картинки, штрих-коды, карты, графические примитивы из отчёта в результирующую Excel-таблицу будут сохранены (но учтите, Libre Office отказался показывать картинки, только MS Excel).

Таблица с иллюстрациями в XLS biff8

Вот так выгядит документ с иллюстрациями (рыбки) в Biff8 XLS. Каждая картинка в собственной ячейке.

отчёт с картами в XLS biff8

Отчёт с картами после сохранения в формат Excel XLS (biff8). Некоторые ячейки были объединены.

Но и ограничения есть - вызваны самим выбранным форматом! На количество выгоняемых на одном листе Excel строк и столбцов - вот вам прямо кусок из кода:

Иначе бы оно при открытии сам MS Excel вываливался с ошибкой и не открывал бы таблицу. Формат, напомню, не развивается и уже давно морально устарел. Радует, что Microsoft не стоял на месте и (несколько позже, конечно, чем Fast Reports) понял таки преимущества XML в качестве базы для организации формата хранения. И о том, как сохранить из Delphi/Lazarus в Excel XML расскажем в следующей статье.

Читайте также: