关于操作excel的资料不多 此文只为新手整理一下用VC操作excel的一个思路~~
以前给表头合并单格总是古板的一个格一个格去查,但是每个表头合并单元格肯定不是固定的,一个个查去实在是浪费精力 浪费时间
所以就写个小算法吧~
#include "excel.h" //别忘把excel.h excel.cpp拷贝到工程下面 然后引入!
#include "comdef.h"
char szFilter[]="Text files(*.xls)|*.xls||";
char szExt[]="xls";
char szName[]="*.xls";
CFileDialog dialog(false, szExt, szName,0,szFilter,this);
dialog.m_ofn.lpstrTitle="存放文件夹";
if(dialog.DoModal()==IDOK)//弹出CFileDialog 判断用户是否点击确定按钮
{
CString str;
str=dialog.GetPathName();
CFile f;
CFileException e;
if( !f.Open( str, CFile::modeCreate | CFile::modeWrite, &e ) )
{
MessageBox("创建文件失败!!","XX软件",MB_ICONSTOP);
return;
}//创建并打开文件
//从VC中的Microsoft FlexGrid控件逐行逐列读取数据并到str中
CString jc="";
for(int i=0;i<m_grid.GetRows();i++)
{
for(int j=0;j<m_grid.GetCols();j++)
{
CString temp=m_grid.GetTextMatrix(i,j);
temp.TrimLeft();
temp.TrimRight();
jc+=temp+" ";
}
jc=jc.Left(jc.GetLength()-1);
jc+="/r/n";
f.Write(jc,jc.GetLength());
jc="";
}
f.Close();
CString sheetname;
_Application ExcelApp;
Workbooks wbsMyBooks;
_Workbook wbMyBook;
Worksheets wssMysheets;
_Worksheet wsMysheet;
Range rgMyRge;
COleVariant vResult,vsty;
COleVariant
covTrue((short)TRUE),
covFalse((short)FALSE),
covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
str = dialog.GetPathName();
sheetname = dialog.GetFileName();
sheetname = sheetname.Left(sheetname.Find(".xls"));
try
{
COleVariant covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
//(启动Excel)
if(!ExcelApp.CreateDispatch("Excel.Application",NULL))
{
AfxMessageBox("创建Excel服务失败!");
return;
}
wbsMyBooks.AttachDispatch(ExcelApp.GetWorkbooks(),true);
wbMyBook = wbsMyBooks.Add(covOptional);
//打开excel文件
wbMyBook.AttachDispatch(wbsMyBooks.Open(str,
covOptional,covOptional,covOptional,covOptional,covOptional,
covOptional,covOptional,covOptional,covOptional,covOptional,
covOptional,covOptional));
//得到Worksheets
wssMysheets.AttachDispatch(wbMyBook.GetWorksheets(),true);
//得到sheet1
wsMysheet.AttachDispatch(wssMysheets.GetItem(_variant_t(sheetname)),true);
//得到全部Cells,此时,rgMyRge是cells的集合
rgMyRge.AttachDispatch(wsMysheet.GetCells(),true);
Range usedRange;
Range unionRange;
Range uinCount;
usedRange.AttachDispatch(wsMysheet.GetUsedRange());
rgMyRge.AttachDispatch(usedRange.GetRows());
long iRowNum=rgMyRge.GetCount(); //已经使用的行数
rgMyRge.AttachDispatch(usedRange.GetColumns());
long iColNum=rgMyRge.GetCount(); //已经使用的列数
//设置所有列类型,都是文本类型
// CString jc="";
CString strHcell,strZcell,str;
int nCell1,nCell2;
_variant_t vRange1;
_variant_t vRange2;
_variant_t vRange3;
_variant_t vRange4;
vRange1.vt =1;
vRange1.lVal =1;
vRange2.vt =VT_I2;
vRange2.lVal =2;
vRange3.vt =VT_I2;
vRange3.lVal =1;
vRange4.vt = VT_UI4;
vRange4.uintVal =RGB(0,0,0);
//画excel边框
for(int i=3;i<iRowNum;i++)
{
for(int k=0;k<=iColNum;k++)
{
str.Format("%d",i+1);
strHcell="A"+str;
nCell1=k%26;
nCell2=(k-1)/26;
if(nCell1==0)
{
if(iColNum<26)
nCell1 = iColNum;
else
nCell1=26;
}
if(nCell2==0)
{
strZcell=64+nCell1;
strZcell=strZcell+"4";
}
else
{
strZcell=64+nCell2;
str=64+nCell1;
strZcell=strZcell+str;
strZcell=strZcell+"4";
}
Range myallrange=wsMysheet.GetRange(COleVariant(strHcell),COleVariant(strZcell));
myallrange.BorderAround(vRange1,vRange2,vRange3,vRange4);
myallrange.ReleaseDispatch();
}
}
CString strName("");
CString betterName("");
int RowCount=0;
int ColCount=0;
//VC操作excel实现表头合并单元格的算法(当然你要合并数据行也可以)
int startRow = 1; //表头从哪行开始就设置为几
int endRow = 3; //表头结束行+1 如excel中前两行为表头 那我们就设置endRow = 2+1;(注:2代表 表头在第二行结束)
for(int x=startRow;x<endRow;x++)
{
for(int y=1;y<=iColNum;y++)
{
usedRange.AttachDispatch(wsMysheet.GetCells());
unionRange.AttachDispatch(usedRange.GetItem (COleVariant((long)x),COleVariant((long)y)).pdispVal );//获得第x行第y列的数据
vResult=unionRange.GetValue();
if(vResult.vt==VT_R8)
{
strName.Format("%f",vResult.dblVal);
}
else
strName=vResult.bstrVal;
if(strName == "")
continue;
for(int i=0;i<15;i++)
{
uinCount.AttachDispatch(usedRange.GetItem (COleVariant((long)(x)),COleVariant((long)(y+i+1))).pdispVal );
vResult=uinCount.GetValue();
if(vResult.vt==VT_R8)
betterName.Format("%f",vResult.dblVal);
else if(vResult.vt==VT_BSTR)
betterName = vResult.bstrVal;
else
break;
if(betterName==strName)
RowCount+=1;
else
break;;
}
if(RowCount == 0)
{
for(int i=0;i<15;i++)
{
uinCount.AttachDispatch(usedRange.GetItem (COleVariant((long)(x+1+i)),COleVariant((long)(y))).pdispVal );
vResult=uinCount.GetValue();
if(vResult.vt==VT_R8)
betterName.Format("%f",vResult.dblVal);
else if(vResult.vt==VT_BSTR)
betterName = vResult.bstrVal;
else
break;
if(betterName==strName)
ColCount+=1;
else
break;
}
}
if(RowCount !=0 && ColCount==0)
{
for(int r=0;r<RowCount;r++)
{
usedRange.SetItem(COleVariant((long)(x)),COleVariant((long)(y+r+1)),COleVariant(""));
}
unionRange.AttachDispatch(unionRange.GetResize(COleVariant((long)1),COleVariant((long)(RowCount+1))));
unionRange.Merge(COleVariant((long)0)); //合并单元格 一行多列合并
unionRange.SetHorizontalAlignment(COleVariant((short)3));//设置名头水平对齐方式为水平居中
}
if(ColCount!=0 && RowCount==0)
{
for(int r=0;r<ColCount;r++)
{
usedRange.SetItem(COleVariant((long)(x+r+1)),COleVariant((long)(y)),COleVariant(""));
}
unionRange.AttachDispatch(unionRange.GetResize(COleVariant((long)(ColCount+1)),COleVariant((long)(1))));
unionRange.Merge(COleVariant((long)0)); //合并单元格 多行一列合并
unionRange.SetHorizontalAlignment(COleVariant((short)3));//设置名头水平对齐方式为水平居中
}
RowCount=0;
ColCount=0;
strName="";
betterName="";
}
}
uinCount.ReleaseDispatch();
usedRange.ReleaseDispatch();
unionRange.ReleaseDispatch();
rgMyRge.ReleaseDispatch();
}
catch(...)
{
ExcelApp.SetUserControl(true);
rgMyRge.ReleaseDispatch();
wsMysheet.ReleaseDispatch();
wssMysheets.ReleaseDispatch();
wbMyBook.ReleaseDispatch();
wbsMyBooks.ReleaseDispatch();
ExcelApp.ReleaseDispatch();
ExcelApp.Quit();
::MessageBox(NULL,"General Exception caught.","Catch-All",MB_SETFOREGROUND|MB_OK);
return;
}
MessageBox("excel写入成功!!","XX软件",MB_ICONEXCLAMATION);
}
//此种用VC操作excel的思路是
一:创建一个文件扩展名为.xls的文件
二:把数据写入到文件中 关闭文件
三:启动excel打开要进行操作的excel文件
四:关闭所有连接以确保关闭excel文件时进程也杀掉了
当然 这只是其中一种方法 还可以创建一个excel模板,直接在模板里写数据 操作完成后一起保存。免去了创建文件 关闭 再打开的繁琐。