RSS

Читаем файл Excel (xls) в Delphi

При написании бизнес приложений на 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
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

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 жирным. Все дополнения постарался по максимуму раскомментить

Прикрепленный файл: excel_open_in_delphi.zip