라자루스로 만들어 보는 비밀번호 관리 프로그램 [뭐였더라] (5) 엑셀파일 출력 II
라자루스로 만들어 보는 비밀번호 관리 프로그램 [뭐였더라] (2) 데이터베이스
라자루스로 만들어 보는 비밀번호 관리 프로그램 [뭐였더라] (3) 기타기능
라자루스로 만들어 보는 비밀번호 관리 프로그램 [뭐였더라] (4) 엑셀파일 출력 I
라자루스로 만들어 보는 비밀번호 관리 프로그램 [뭐였더라] (5) 엑셀파일 출력 II
데이터베이스를 엑셀 파일로 출력하는 것에 성공했지만, 마음에 들지 않는 점이 있다. 실행화면에 표시되는 DBGrid 의 데이터와 일치하지 않는 것이다.
데이터베이스와 DBGrid 에 표시되는 데이터에는 차이가 있다. 데이터베이스에는 PK 필드가 있지만 DBGrid 에는 표시되지 않는다. 그리고 데이터베이스의 필드이름은 영어로 표시되어 있지만 , DBGrid 의 필드에는 별도의 캡션이 표시된다. FPSExport 에서 제공하는 내보내기(Export) 프로시져들은 기본적으로 데이터베이스 내용 그대로 내보내는 것을 전제로 하고 있다. DBGrid 에 표시되는 모습 그대로 엑셀 파일로 출력하려면 어떻게 해야 할까.
엑셀 문서는 한개의 페이지가 WorkSheet , WorkSheet 가 여러개 모여서 WorkBook 으로 구성된다. WorkSheet 내의 한개의 칸은 Cell 이라고 부른다. WorkBook 을 Create 하고 WorkSheet 를 Add 하면 한개의 엑셀 문서가 완성된다. uses 에 fpspreadsheet 와 fpstypes 를 추가시키고 다음 문장을 입력하면 문서가 만들어진다.
Book := TsWorkBook.Create;
Sheet := Book.AddWorksheet('비밀번호 관리');
엑셀 문서를 만들고 그 내부에 구현해야 하는 기능은 다음과 같다.
- DBGrid 컬럼의 [Visible] Property 가 True 일 때만 엑셀파일로 출력
- DBGrid 컬럼의 캡션을 엑셀파일의 첫행에 출력
DBGrid 의 Column 이 Visible 일 때만 엑셀문서에 쓰기한다. 첫행은 DBGrid 의 Caption 을 WriteText 한다. DBGrid 의 Column 이 Visible 일 때만 VisCol 을 1 증가시켜서 엑셀문서의 Column 을 증가시키는 원리를 주목해보자.
for Col := 0 to ADataSet.Fields.Count - 1 do
begin
if AGrid.Columns[Col].Visible then ////DBGrid 의 컬럼이 Visible 일 때만 진행한다.
begin
Cell := Sheet.WriteText(Row, VisCol, AGrid.Columns[Col].Title.Caption);
Sheet.WriteBackgroundColor(cell, clMoneyGreen); //첫 행의 배경색
VisCol := VisCol + 1;
end;
end;
전체코드는 다음과 같다.
procedure TMainForm.ExportDBGridToExcel(AGrid: TDBGrid; AFileName: String);
var
Book: TsWorkBook;
Sheet: TsWorkSheet;
Row, Col, VisCol: Integer;
Cell: PCell;
ADataSet: TDataSet;
Field: TField;
begin
ADataSet := AGrid.DataSource.DataSet;
Book := TsWorkBook.Create;
Sheet := Book.AddWorksheet('비밀번호 관리');
Row := 0; Col := 0; VisCol := 0;
try
//DBGrid 의 캡션을 워크시트의 첫행에 출력한다.
for Col := 0 to ADataSet.Fields.Count - 1 do
begin
if AGrid.Columns[Col].Visible then //DBGrid 의 컬럼이 Visible 일 때만 진행한다.
begin
Cell := Sheet.WriteText(Row, VisCol, AGrid.Columns[Col].Title.Caption);
Sheet.WriteBackgroundColor(cell, clMoneyGreen); //첫 행의 배경색
VisCol := VisCol + 1;
end;
end;
Inc(Row); //워크시트를 두번재 행으로 이동
ADataSet.First; //데이터세트의 첫행으로 이동
while not ADataSet.EOF do //마지막 레코드까지 계속 진행한다.
begin
VisCol := 0;
for Col := 0 to AGrid.Columns.Count - 1 do
begin
if AGrid.Columns[Col].Visible then //DBGrid 의 컬럼이 visible 일때만 진행한다.
begin
Field := AGrid.Columns[Col].Field; //DBGrid 의field 를 넣고 type 을 결정한다.
if Field.DataType in [ftInteger, ftWord, ftSmallint, ftAutoinc, ftLargeInt] then
Sheet.WriteNumber(Row, VisCol, ADataSet.Fields[Col].AsInteger)
else if Field.DataType in [ftBCD, ftFloat, ftFMTBcd] then
Sheet.WriteNumber(Row, VisCol, ADataSet.Fields[Col].AsFloat)
else if Field.DataType in [ftCurrency] then
Sheet.WriteCurrency(Row, VisCol, ADataSet.Fields[Col].AsFloat)
else if Field.DataType in [ftString, ftFixedChar] then
Sheet.WriteText(Row, VisCol, ADataSet.Fields[Col].AsString)
else if Field.DataType in [ftWideMemo, ftWideString, ftFixedWideChar] then
Sheet.WriteText(Row, VisCol, UTF8Encode(ADataSet.Fields[Col].AsWideString))
else if Field.DataType in [ftMemo, ftFmtMemo, ftWideMemo] then
Sheet.WriteText(Row, VisCol, ADataSet.Fields[Col].AsString)
else if Field.DataType = ftBoolean then
Sheet.WriteBoolValue(Row, VisCol, ADataSet.Fields[Col].AsBoolean)
else
Sheet.WriteText(Row, VisCol, ADataSet.Fields[Col].AsString);
VisCol := VisCol + 1; //DBGrid 의 컬럼이 visible 일때만 워크시트의 오른쪽으로 증가시킨다.
end;
end;
Inc(Row);
ADataSet.Next;
end;
Book.WriteToFile(AFileName, sfOOXML, True);
QuestionDlg('엑셀 내보내기', '엑셀파일 ' + AFileName +
' 가 만들어졌습니다.', mtCustom, [mrYes, '확인'], '');
finally
Book.Free;
end;
end;
최종 결과물은 다음과 같다.
라자루스로 만들어 보는 비밀번호 관리 프로그램 [뭐였더라] (2) 데이터베이스
라자루스로 만들어 보는 비밀번호 관리 프로그램 [뭐였더라] (3) 기타기능
라자루스로 만들어 보는 비밀번호 관리 프로그램 [뭐였더라] (4) 엑셀파일 출력 I
라자루스로 만들어 보는 비밀번호 관리 프로그램 [뭐였더라] (5) 엑셀파일 출력 II