首页 >excel操作 > 内容

VC中操作excel表格

2023年1月24日 12:57

摘要:使用Microsoft Office所带的控件来实现代码操作excel表格。

最近由于工作需要,不得不操作Excel,包括基本的数据输入输出、字体设置、颜色设置、单元格的合并、填充色的设置,当然还包括图表的生成以及渐近线的操作等。折腾了许久,项目终于完成了^_^。现在将学习操作Excel的点点滴滴记录下来和大家一同分享,也作为自己的一次总结。

1、Excel的对象模型(有人称其为层次结构)

打开一个Excel工作表,点击“工具”->“宏”->“Visual Basic 编辑器”选项打开VB的编辑器,打开帮助文档,里面“Microsoft Excel Visual Basic 参考”下的“Microsoft Excel 对象模型”展示了完整的Excel的层次结构,是不是有点类似于MFC的继承图表啊?利用帮助文档我们可以找到一些需要的知识,下面介绍一些类:

_Application:表示整个的Excel应用程序,包含一个工作簿集合

Workbooks:工作簿集合,包含N个工作簿(Workbook)

_Workbook:工作簿,包含一个工作表(sheets)集合

Worksheets:工作表集合,包含N个工作表

_Worksheet:工作表,也就是我们在Excel中看到的Sheet1、Sheet2、Sheet3,它是我们操作Excel的基本单位

Range:这是单元格的集合,我们知道Excel是由一个个的单元格组成的,通过Range来操作单元格

Font:用于设置单元格的字体、颜色、字号、粗体设置

Interior:设置底色

Boards:设置区域内所有单元格的边框,如果要设置一组区域的外边框的话用Rang->BorderAround设置

下面用一个具体的例子来说明怎么通过MFC来操作Excel

2、Excel库的插入

在我们MFC的工程中,按Ctrl+W打开MFC类向导对话框,点击“Add Class...”->“From a type Library...”,找到你所使用的excel类型库,我使用的在目录C:/Program Files/Microsoft Office/OFFICE11下的“EXCEL.EXE”文件,查找时文件类型选“All Files”,然后添加我们所需要的类,通常以上列举的前6类是必须的,其它的需要时再添加。我不认为全部添加是一种好的做法,一个我觉得很乱,另外生成的excel.cpp文件会很大。我建议浏览一遍这些类,这样当你做些操作时可以更清楚的知道需要添加哪些类。添加完需要的类后,我们就可以来做一些基本的操作了。

3、Com支持库的初始化

通常在App的InitInstance()里面加入初始化和关闭COM库的操作,在DoModal()调用之前加入初始化的代码:

  1. if(CoInitialize(NULL)!=0)
  2. {
  3. AfxMessageBox("初始化COM支持库失败!");
  4. exit(1);
  5. }

在return之前加入CoUninitialize(); 关闭CON库。

4、代码演示一些基本的操作

首先别忘了包含头文件“excel.h”,若用到_variant_t()时,需要包含头文件“comdef.h”和“comutil.h”,否则会出现错误:

error C2065: '_variant_t' : undeclared identifier”。

下面的代码包括了一些基本的操作:

  1. //变量的定义
  2. _Applicationapp;
  3. Workbooksbooks;
  4. _Workbookbook;
  5. Worksheetssheets;
  6. _Worksheetsheet;
  7. Rangerange;
  8. LPDISPATCHlpDisp;
  9. COleVariantvResult;
  10. CStringstr="";
  11. COleVariant
  12. covTrue((short)TRUE),
  13. covFalse((short)FALSE),
  14. covOptional((long)DISP_E_PARAMNOTFOUND,VT_ERROR);
  15. //创建Excel2003服务器(启动Excel)
  16. if(!app.CreateDispatch("Excel.Application",NULL))
  17. {
  18. AfxMessageBox("CreateExcelservicefailure!");
  19. return;
  20. }
  21. //设置为FALSE时,后面的app.Quit();注释要打开
  22. //否则EXCEL.EXE进程会一直存在,并且每操作一次就会多开一个进程
  23. app.SetVisible(TRUE);
  24. books.AttachDispatch(app.GetWorkbooks(),true);
  25. /*
  26. *打开一个工作簿。
  27. *Excel2000只需要13个参数就行,Excel2003需要15个参数
  28. */
  29. lpDisp=books.Open("E://test.xls",
  30. covOptional,covOptional,covOptional,covOptional,
  31. covOptional,covOptional,covOptional,covOptional,
  32. covOptional,covOptional,covOptional,covOptional,
  33. covOptional,covOptional);
  34. ASSERT(lpDisp);
  35. book.AttachDispatch(lpDisp);
  36. //得到Worksheets
  37. sheets.AttachDispatch(book.GetWorksheets(),true);
  38. //得到Worksheet
  39. sheet.AttachDispatch(sheets.GetItem(_variant_t((short)(1))));
  40. //得到全部Cells
  41. range.AttachDispatch(sheet.GetCells(),true);
  42. //往单元格A1里写入字符串数据,就像操作矩阵一样,第1行第1列
  43. range.SetItem(_variant_t((LONG)1),_variant_t((LONG)1),_variant_t("helloword!"));
  44. //往单元格A2里写入时间数据
  45. range.AttachDispatch(sheet.GetRange(_variant_t("A2"),_variant_t("A2")),true);
  46. range.SetValue2(_variant_t("2011/02/15"));
  47. //往单元格A3~A6里写入浮点数据
  48. range.AttachDispatch(sheet.GetRange(_variant_t("A3"),_variant_t("A6")),true);
  49. range.SetValue2(_variant_t((double)3.14));
  50. //设置单元格的列宽为12
  51. range.AttachDispatch(sheet.GetRange(_variant_t("A1"),_variant_t("A1")),true);
  52. range.SetColumnWidth(_variant_t((long)12));
  53. //所有单元格居中显示
  54. range.AttachDispatch(sheet.GetCells(),true);
  55. range.SetHorizontalAlignment(_variant_t((long)-4108));//-4108:居中,-4131:靠左,-4152:靠右
  56. range.SetVerticalAlignment(_variant_t((long)-4108));//-4108:居中,-4160:靠上,-4107:靠下
  57. //读取单元格的数据,第4行第1列
  58. range.AttachDispatch(range.GetItem(_variant_t((long)(4)),_variant_t((long)(1))).pdispVal);
  59. vResult=range.GetValue(covOptional);
  60. switch(vResult.vt)
  61. {
  62. caseVT_BSTR://字符串
  63. str=vResult.bstrVal;
  64. break;
  65. caseVT_R8://8字节的数字
  66. str.Format("%f",vResult.dblVal);
  67. break;
  68. caseVT_DATE://时间格式
  69. SYSTEMTIMEst;
  70. VariantTimeToSystemTime(vResult.date,&st);
  71. break;
  72. caseVT_EMPTY://单元格空的
  73. str="";
  74. break;
  75. }
  76. //MessageBox(str);
  77. Fontft;//要插入excel类库里面的Font类,下面类似
  78. range.AttachDispatch(sheet.GetRange(_variant_t("A3"),_variant_t("A5")),true);
  79. ft.AttachDispatch(range.GetFont());
  80. ft.SetName(_variant_t("华文行楷"));//字体
  81. ft.SetSize(_variant_t((long)12));//字号
  82. //ft.SetColorIndex(_variant_t((long)3));//字的颜色:红色
  83. ft.SetColor(_variant_t((long)RGB(255,0,0)));
  84. ft.SetBold(_variant_t((long)1));//1:粗体,0:非粗体
  85. Interiorit;//底色设置
  86. range.AttachDispatch(sheet.GetRange(_variant_t("C3"),_variant_t("E6")),true);
  87. it.AttachDispatch(range.GetInterior());
  88. it.SetColorIndex(_variant_t((long)20));//底色设置为浅青色
  89. Bordersborders;//先设置区域内所有单元格的边框
  90. borders=range.GetBorders();
  91. borders.SetColorIndex(_variant_t((long)1));
  92. borders.SetLineStyle(_variant_t((long)1));
  93. borders.SetWeight(_variant_t((long)2));
  94. //然后设置外边框
  95. //LineStyle=线型(1~13)Weight=线宽ColorIndex=线的颜色(-4105为自动,1为黑色)
  96. range.BorderAround(_variant_t((long)9),_variant_t((long)1),_variant_t((long)1),vtMissing);
  97. range.AttachDispatch(sheet.GetRange(_variant_t("C8"),_variant_t("D9")),true);
  98. //合并单元格
  99. range.Merge(_variant_t((long)0));
  100. book.Save();//保存Excel的内容
  101. //app.SetDisplayAlerts(false);//不弹出对话框询问是否保存
  102. //app.Quit();//退出
  103. //释放对象
  104. range.ReleaseDispatch();
  105. sheet.ReleaseDispatch();
  106. sheets.ReleaseDispatch();
  107. book.ReleaseDispatch();
  108. books.ReleaseDispatch();
  109. app.ReleaseDispatch();
[c-sharp] view plain copy
  1. .h文件:
  2. #include"comdef.h"
  3. #include"excel.h"
  4. classExcelFile
  5. {
  6. public:
  7. voidShowInExcel(boolbShow);
  8. CStringGetCell(intiRow,intiColumn);
  9. intGetCellInt(intiRow,intiColumn);
  10. intGetRowCount();
  11. intGetColumnCount();
  12. boolLoadSheet(intiIndex);
  13. CStringGetSheetName(intiIndex);
  14. staticvoidInitExcel();
  15. staticvoidReleaseExcel();
  16. intGetSheetCount();
  17. boolOpen(CStringFileName);
  18. ExcelFile();
  19. virtual~ExcelFile();
  20. protected:
  21. private:
  22. static_Applicationm_ExcelApp;
  23. Workbooksm_Books;
  24. _Workbookm_Book;
  25. Worksheetsm_sheets;
  26. _Worksheetm_sheet;
  27. Rangem_Rge;
  28. };
  29. .cpp文件:
  30. ExcelFile::ExcelFile()
  31. {
  32. }
  33. ExcelFile::~ExcelFile()
  34. {
  35. m_Rge.ReleaseDispatch();
  36. m_sheet.ReleaseDispatch();
  37. m_sheets.ReleaseDispatch();
  38. m_Book.ReleaseDispatch();
  39. m_Books.ReleaseDispatch();
  40. }
  41. voidExcelFile::InitExcel()
  42. {
  43. //创建Excel2000服务器(启动Excel)
  44. if(!m_ExcelApp.CreateDispatch("Excel.Application",NULL))
  45. {
  46. AfxMessageBox("创建Excel服务失败!");
  47. exit(1);
  48. }
  49. }
  50. voidExcelFile::ReleaseExcel()
  51. {
  52. m_ExcelApp.ReleaseDispatch();
  53. }
  54. boolExcelFile::Open(CStringFileName)
  55. {
  56. //打开excel文件
  57. //利用模板文件建立新文档
  58. m_Books.AttachDispatch(m_ExcelApp.GetWorkbooks(),true);
  59. LPDISPATCHlpDis=NULL;
  60. lpDis=m_Books.Add(_variant_t(FileName));//如何判断文件是否打开?
  61. if(lpDis)
  62. {
  63. m_Book.AttachDispatch(lpDis);
  64. //得到Worksheets
  65. m_sheets.AttachDispatch(m_Book.GetWorksheets(),true);
  66. returntrue;
  67. }
  68. returnfalse;
  69. }
  70. intExcelFile::GetSheetCount()
  71. {
  72. returnm_sheets.GetCount();
  73. }
  74. CStringExcelFile::GetSheetName(intiIndex)
  75. {
  76. _Worksheetsheet;
  77. sheet.AttachDispatch(m_sheets.GetItem(_variant_t((long)iIndex)),true);
  78. CStringname=sheet.GetName();
  79. sheet.ReleaseDispatch();
  80. returnname;
  81. }
  82. boolExcelFile::LoadSheet(intiIndex)
  83. {
  84. LPDISPATCHlpDis=NULL;
  85. m_Rge.ReleaseDispatch();
  86. m_sheet.ReleaseDispatch();
  87. lpDis=m_sheets.GetItem(_variant_t((long)iIndex));
  88. if(lpDis)
  89. {
  90. m_sheet.AttachDispatch(lpDis,true);
  91. m_Rge.AttachDispatch(m_sheet.GetCells(),true);
  92. returntrue;
  93. }
  94. returnfalse;
  95. }
  96. intExcelFile::GetColumnCount()
  97. {
  98. Rangerange;
  99. RangeusedRange;
  100. usedRange.AttachDispatch(m_sheet.GetUsedRange(),true);
  101. range.AttachDispatch(usedRange.GetColumns(),true);
  102. intcount=range.GetCount();
  103. usedRange.ReleaseDispatch();
  104. range.ReleaseDispatch();
  105. returncount;
  106. }
  107. intExcelFile::GetRowCount()
  108. {
  109. Rangerange;
  110. RangeusedRange;
  111. usedRange.AttachDispatch(m_sheet.GetUsedRange(),true);
  112. range.AttachDispatch(usedRange.GetRows(),true);
  113. intcount=range.GetCount();
  114. usedRange.ReleaseDispatch();
  115. range.ReleaseDispatch();
  116. returncount;
  117. }
  118. CStringExcelFile::GetCell(intiRow,intiColumn)
  119. {
  120. Rangerange;
  121. range.AttachDispatch(m_Rge.GetItem(COleVariant((long)iRow),COleVariant((long)iColumn)).pdispVal,true);
  122. COleVariantvResult=range.GetValue2();
  123. CStringstr;
  124. if(vResult.vt==VT_BSTR)//字符串
  125. {
  126. str=vResult.bstrVal;
  127. }
  128. elseif(vResult.vt==VT_INT)
  129. {
  130. str.Format("%d",vResult.pintVal);
  131. }
  132. elseif(vResult.vt==VT_R8)//8字节的数字
  133. {
  134. str.Format("%f",vResult.dblVal);
  135. //str.Format("%.0f",vResult.dblVal);
  136. //str.Format("%1f",vResult.fltVal);
  137. }
  138. elseif(vResult.vt==VT_DATE)//时间格式
  139. {
  140. SYSTEMTIMEst;
  141. VariantTimeToSystemTime(vResult.date,&st);
  142. }
  143. elseif(vResult.vt==VT_EMPTY)//单元格空的
  144. {
  145. str="(NULL)";
  146. }
  147. range.ReleaseDispatch();
  148. returnstr;
  149. }
  150. intExcelFile::GetCellInt(intiRow,intiColumn)
  151. {
  152. Rangerange;
  153. range.AttachDispatch(m_Rge.GetItem(COleVariant((long)iRow),COleVariant((long)iColumn)).pdispVal,true);
  154. COleVariantvResult=range.GetValue2();
  155. intnum;
  156. num=(int)vResult.date;
  157. range.ReleaseDispatch();
  158. returnnum;
  159. }
  160. voidExcelFile::ShowInExcel(boolbShow)
  161. {
  162. m_ExcelApp.SetVisible(bShow);
  163. }


参考文章:https://blog.csdn.net/qianqiang1989/article/details/9470761

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时候联系我们修改或删除,在此表示感谢。

特别提醒:

1、请用户自行保存原始数据,为确保安全网站使用完即被永久销毁,如何人将无法再次获取。

2、如果上次文件较大或者涉及到复杂运算的数据,可能需要一定的时间,请耐心等待一会。

3、请按照用户协议文明上网,如果发现用户存在恶意行为,包括但不限于发布不合适言论妄图

     获取用户隐私信息等行为,网站将根据掌握的情况对用户进行限制部分行为、永久封号等处罚。

4、如果文件下载失败可能是弹出窗口被浏览器拦截,点击允许弹出即可,一般在网址栏位置设置

5、欢迎将网站推荐给其他人,网站持续更新更多功能敬请期待,收藏网站高效办公不迷路。

      



登录后回复

共有0条评论