程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> 在C++ Builder中用Ole控制Excel表

在C++ Builder中用Ole控制Excel表

編輯:關於C++

筆者在實際工作中經常用Excel表做數據報表,大多數表格的數據都要從數據庫中讀取,這樣我就用C++Builder做了一個報表程序,方便了很多,現在把它共享給C++Builder愛好者們,就算為豐富C++Builder的文檔資料做點事情吧。

首先把Excel報表文件保存到一個指定目錄下,最好放在可執行程序的子目錄下,作為模板文件。可以把報表標題、表頭等設置好。這裡是保存在trpt子目錄下。

然後建一個report目錄,作為報表目標文件夾,存放填好數據的報表,可以由用戶直接操作。

首先確定在你的機器中裝有Office。這裡一Office2000為例。

在C++Builder中新建一個工程,在窗體Form1上面放一個兩個按鈕SaveButton和ReadButton,分別用來保存數據到Excel表和顯示剛剛保存的Excel表。

在SaveButton按鈕的單擊事件中把從數據庫中取到的數據放入到指定的Excel表中並將改文件拷貝到report目錄下。在ReadButto按鈕的單擊事件中顯示report目錄下的報表文件,方便用戶修改和另外保存。

在Form1.h頭文件中定義幾個變量:

private:
Variant Ex,Wb,Sheet,ERange,EBorders;

並在文件頭中包含如下語句:

#include "Excel_2K_SRVR.h"
#include

在Form1.cpp的文件頭中加入

#pragma link "Excel_2K_SRVR"

主要代碼如下:

void __fastcall TForm1:: SaveButtonClick(TObject *Sender)
{
try
{
SaveButton->Enabled = false;
ReadButton->Enabled = false;//使兩個按鈕無效
file://取報表文件CardSend.xls的完整目錄名
AnsiString ExcelFileName = GetCurrentDir()+"\\trpt\\table.xls";
if(!FileExists(ExcelFileName))
{
Application->MessageBox("報表模板文件不存在,無法打開!",
"錯誤",MB_ICONSTOP|MB_OK);
return;
}
file://建立Excel的Ole對象Ex
try
{
Ex = Variant::CreateObject("Excel.Application");
}
catch(...)
{
Application->MessageBox("無法啟動Excel","錯誤",MB_ICONSTOP|MB_OK);
return;
}
file://設置Excel為不可見
Ex.OlePropertySet("Visible",false);
file://打開指定的Excel報表文件。報表文件中最好設定只有一個Sheet。
Ex.OlePropertyGet("WorkBooks").OleProcedure("Open",ExcelFileName.c_str());
Wb = Ex.OlePropertyGet("ActiveWorkBook");
Sheet = Wb.OlePropertyGet("ActiveSheet");//獲得當前默認的Sheet
file://清空Excel表,這裡是用循環清空到第300行。對於一般的表格已經足夠了。
AnsiString strRowTemp;
AnsiString strRange;
int iCols,iRows;//記錄列數和行數
/*從第三行開始,到第300行止。一般第一行是表標題,第二行是副標題或者制表日期。*/
for(iRows=3;iRows<300;iRows++)
{ file://假設只有6列。
for (iCols = 1;iCols < 7; iCols++)
{
file://清空行
Sheet.OlePropertyGet("Cells",iRows,iCols).OlePropertySet("Value","");
}
file://去掉表格邊框
strRange = "A"+IntToStr(iRows)+":F"+IntToStr(iRows);//獲取操作范圍
ERange = Sheet.OlePropertyGet("Range",strRange.c_str());
EBorders = ERange.OlePropertyGet("Borders");//獲取邊框對象
EBorders.OlePropertySet("linestyle",xlNone);
}
AnsiString strPtrDate; file://存放當前日期,作為制表日期
DateSeparator = '-';
ShortDateFormat = "yyyy/m/d";//設置為年/月/日格式
strPtrDate = DateToStr(Date());//取當前日期
AnsiString strYear = strPtrDate.SubString(1,4);
strPtrDate = strPtrDate.SubString(6,strPtrDate.Length()-5);
AnsiString strMonth = strPtrDate.SubString(1,strPtrDate.Pos("-")-1);
AnsiString strDay =
strPtrDate.SubString(strPtrDate.Pos("-")+1,
strPtrDate.Length()-strPtrDate.Pos("-"));
strPtrDate = strYear+"年"+strMonth+"月"+strDay+"日";
AnsiString strData = "報表標題";//報表標題
file://將報表標題置於第一行第一列。在此之前,應將報表文件的標題格式設定好。
Sheet.OlePropertyGet("Cells",1,1).OlePropertySet("Value",
strData.c_str());
file://將制表日期置於表格第二行的右側。
Sheet.OlePropertyGet("Cells",2,5).OlePropertySet("Value",
strPtrDate.c_str());
iRows = 3;//在第三行放置表格的列名
Sheet.OlePropertyGet("Cells",iRows,1).OlePropertySet("Value","列名1");
Sheet.OlePropertyGet("Cells",iRows,2).OlePropertySet("Value","列名2");
Sheet.OlePropertyGet("Cells",iRows,3).OlePropertySet("Value","列名3");
Sheet.OlePropertyGet("Cells",iRows,4).OlePropertySet("Value","列名4");
Sheet.OlePropertyGet("Cells",iRows,5).OlePropertySet("Value","列名5");
Sheet.OlePropertyGet("Cells",iRows,6).OlePropertySet("Value","列名6");
file://畫表格邊框,在A3:F3之間取范圍
strRange = "A"+IntToStr(iRows)+":F"+IntToStr(iRows);
ERange = Sheet.OlePropertyGet("Range",strRange.c_str());
EBorders = ERange.OlePropertyGet("Borders");
EBorders.OlePropertySet("linestyle",xlContinuous);
EBorders.OlePropertySet("weight",xlThin);
EBorders.OlePropertySet("colorindex",xlAutomatic);
iRows++;
file://從數據庫中取數據(略),假設數據集放入Query1中。
Query1->Open();//打開數據集
file://循環取數
while(!Query1->Eof)
{
file://循環取字段的數據放到Excel表對應的行列中
for(iCols=1;iCols<7;iCols++)
{
strRowTemp = Query1->Fields->Fields[iCols-1]->AsString;
Sheet.OlePropertyGet("Cells",iRows,iCols).OlePropertySet("Value",
strRowTemp.c_str());
}
file://畫該行的表格邊框
strRange = "A"+IntToStr(iRows)+":F"+IntToStr(iRows);
ERange = Sheet.OlePropertyGet("Range",strRange.c_str());
EBorders = ERange.OlePropertyGet("Borders");
EBorders.OlePropertySet("linestyle",xlContinuous);
EBorders.OlePropertySet("weight",xlThin);
EBorders.OlePropertySet("colorindex",xlAutomatic);
iRows++;
Query1->Next();
}//while結束
Wb.OleProcedure("Save");//保存表格
Wb.OleProcedure("Close");關閉表格
Ex.OleFunction("Quit");退出Excel
file://定義目標文件名
AnsiString DestinationFile =
GetCurrentDir()+"\\report\\table.xls";
file://將剛剛修改的Excel表格文件table.xls拷貝到report目錄下
if(!CopyFile(ExcelFileName.c_str(),DestinationFile.c_str(),false))
{
Application->MessageBox("復制文件操作失敗,Excel文件可能正在使用中!",
"錯誤",MB_ICONSTOP|MB_OK);
return;
}
Application->MessageBox("成功完成報表保存!\n可以按\'打開Excel文件\'
按鈕進行報表工作","提示",MB_ICONINFORMATION|MB_OK);
SaveButton ->Enabled = true;
ReadButton ->Enabled=true;
}//try結束
catch(...)
{
Application->MessageBox("操作Excel表格失敗!",
"錯誤",MB_ICONSTOP|MB_OK);
Wb.OleProcedure("Close");
Ex.OleFunction("Quit");
SaveButton ->Enabled = true;
ReadButton ->Enabled=false;
}
}

至此,完成報表數據的寫入工作。如果要對完成的Excel表進行操作,可以點擊"打開Excel表文件按鈕"(ReadButton),進行修改,保存,打印等操作。ReadButton的單擊事件如下實現:

void __fastcall TForm1:: ReadButtonClick(TObject *Sender)
{
try
{
file://指定report目錄下的報表文件用於用戶操作
AnsiString ExcelFileName =
GetCurrentDir();+"\\report\\table.xls";
if(!FileExists(ExcelFileName))
{
Application->MessageBox("Excel表文件不存在,無法打開!",
"錯誤",MB_ICONSTOP|MB_OK);
return;
}
try
{
Ex = Variant::CreateObject("Excel.Application");
}
catch(...)
{
Application->MessageBox("無法啟動Excel","錯誤",MB_ICONSTOP|MB_OK);
return;
}
file://使Excel可見
Ex.OlePropertySet("Visible",true);
file://打開Excel表格文件Table.xls
Ex.OlePropertyGet("WorkBooks").OleProcedure("Open",ExcelFileName.c_str());
}
catch(...)
{
Application->MessageBox("操作Excel表格錯誤!","錯誤",MB_ICONSTOP|MB_OK);
Ex.OleFunction("Quit");
}
}

以上關於C++BuilderExcel表格的操作僅作為個人觀點和水平呈獻給關心此問題的讀者,如果有更好的方式方法,敬請指教,不勝感激。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved