===fag::=============================================================
Excel库的插入
在我们MFC的工程中,按Ctrl+W打开MFC类向导对话框,点击“Add Class…”->“From a type Library…”,找到你所使用的excel类型库,我使用的在目录C:/Program Files/Microsoft Office/OFFICE11(fag::有时时14)下的“EXCEL.EXE”文件,查找时文件类型选“All Files”,然后添加我们所需要的类,通常以上列举的前6类是必须的,其它的需要时再添加。
特别注意:别忘了包含头文件“excel.h”
================================================================
VC操作Excel之基本操作
http://blog.csdn.net/sp_daiyq/article/details/6191233
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()调用之前加入初始化的代码:
[cpp] view plaincopyprint?
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”。
下面的代码包括了一些基本的操作:
[cpp] view plaincopyprint?
1. // 变量的定义
2. _Application app;
3. Workbooks books;
4. _Workbook book;
5. Worksheets sheets;
6. _Worksheet sheet;
7. Range range;
8. LPDISPATCH lpDisp;
9. COleVariant vResult;
10.
11. CString str = “”;
12.
13. COleVariant
14. covTrue((short)TRUE),
15. covFalse((short)FALSE),
16. covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
17.
18. //创建Excel 2003服务器(启动Excel)
19. if (!app.CreateDispatch(“Excel.Application”,NULL))
20. {
21. AfxMessageBox(“Create Excel service failure!”);
22. return;
23. }
24.
25. // 设置为FALSE时,后面的app.Quit();注释要打开
26. // 否则EXCEL.EXE进程会一直存在,并且每操作一次就会多开一个进程
27. app.SetVisible(TRUE);
28. books.AttachDispatch(app.GetWorkbooks(),true);
29.
30. /*
31. * 打开一个工作簿。
32. * Excel 2000 只需要13个参数就行,Excel 2003需要15个参数
33. */
34. lpDisp = books.Open(“E://test.xls”,
35. covOptional, covOptional, covOptional, covOptional,
36. covOptional, covOptional, covOptional, covOptional,
37. covOptional, covOptional, covOptional, covOptional,
38. covOptional, covOptional);
39. ASSERT(lpDisp);
40.
41. book.AttachDispatch(lpDisp);
42.
43. // 得到Worksheets
44. sheets.AttachDispatch(book.GetWorksheets(),true);
45.
46. // 得到Worksheet
47. sheet.AttachDispatch(sheets.GetItem(_variant_t((short)(1))));
48.
49. // 得到全部Cells
50. range.AttachDispatch(sheet.GetCells(),true);
51.
52.
53. // 往单元格A1里写入字符串数据,就像操作矩阵一样,第1行第1列
54. range.SetItem(_variant_t((LONG)1),_variant_t((LONG)1),_variant_t(“hello word!”));
55.
56. // 往单元格A2里写入时间数据
57. range.AttachDispatch(sheet.GetRange(_variant_t(“A2”), _variant_t(“A2”)),true);
58. range.SetValue2(_variant_t(“2011/02/15”));
59.
60. // 往单元格A3~A6里写入浮点数据
61. range.AttachDispatch(sheet.GetRange(_variant_t(“A3”), _variant_t(“A6”)),true);
62. range.SetValue2(_variant_t((double)3.14));
63.
64. // 设置单元格的列宽为12
65. range.AttachDispatch(sheet.GetRange(_variant_t(“A1”), _variant_t(“A1”)),true);
66. range.SetColumnWidth(_variant_t((long)12));
67.
68. // 所有单元格居中显示
69. range.AttachDispatch(sheet.GetCells(),true);
70. range.SetHorizontalAlignment(_variant_t((long)-4108)); // -4108:居中,-4131:靠左,-4152:靠右
71. range.SetVerticalAlignment(_variant_t((long)-4108)); // -4108:居中,-4160:靠上,-4107:靠下
72.
73. // 读取单元格的数据,第4行第1列
74. range.AttachDispatch(range.GetItem(_variant_t((long)(4)),_variant_t((long)(1))).pdispVal );
75. vResult =range.GetValue(covOptional);
76.
77. switch (vResult.vt)
78. {
79. case VT_BSTR: // 字符串
80. str=vResult.bstrVal;
81. break;
82. case VT_R8: // 8字节的数字
83. str.Format(“%f”,vResult.dblVal);
84. break;
85. case VT_DATE: // 时间格式
86. SYSTEMTIME st;
87. VariantTimeToSystemTime(vResult.date, &st);
88. break;
89. case VT_EMPTY: // 单元格空的
90. str=”“;
91. break;
92. }
93. //MessageBox(str);
94.
95. Font ft; // 要插入excel类库里面的Font类,下面类似
96.
97. range.AttachDispatch(sheet.GetRange(_variant_t(“A3”), _variant_t(“A5”)),true);
98. ft.AttachDispatch(range.GetFont());
99. ft.SetName(_variant_t(“华文行楷”)); // 字体
100. ft.SetSize(_variant_t((long)12)); // 字号
101. //ft.SetColorIndex(_variant_t((long)3)); // 字的颜色: 红色
102. ft.SetColor( _variant_t((long) RGB(255, 0, 0) ) );
103. ft.SetBold(_variant_t((long)1)); // 1:粗体,0:非粗体
104.
105. Interior it; // 底色设置
106.
107. range.AttachDispatch(sheet.GetRange(_variant_t(“C3”), _variant_t(“E6”)),true);
108. it.AttachDispatch(range.GetInterior());
109. it.SetColorIndex(_variant_t((long)20)); // 底色设置为浅青色
110.
111. Borders borders; // 先设置区域内所有单元格的边框
112. borders = range.GetBorders();
113. borders.SetColorIndex(_variant_t((long)1));
114. borders.SetLineStyle(_variant_t((long)1));
115. borders.SetWeight(_variant_t((long)2));
116.
117. // 然后设置外边框
118. // LineStyle=线型(1~13) Weight=线宽 ColorIndex=线的颜色(-4105为自动, 1为黑色)
119. range.BorderAround(_variant_t((long)9),_variant_t((long)1),_variant_t((long)1),vtMissing);
120.
121. range.AttachDispatch(sheet.GetRange(_variant_t(“C8”), _variant_t(“D9”)),true);
122. // 合并单元格
123. range.Merge(_variant_t((long)0));
124.
125.
126. book.Save(); // 保存Excel的内容
127.// app.SetDisplayAlerts(false); // 不弹出对话框询问是否保存
128.// app.Quit(); // 退出
129.
130. //释放对象
131. range.ReleaseDispatch();
132. sheet.ReleaseDispatch();
133. sheets.ReleaseDispatch();
134. book.ReleaseDispatch();
135. books.ReleaseDispatch();
136. app.ReleaseDispatch();
VC操作Excel之用ChartWizard自动生成图表
http://blog.csdn.net/sp_daiyq/article/details/6191548
在用VC操作Excel的时候,生成图表有时是不可避免的,这里记下如何通过ChartWizard来简单生成一个图表。首先我们得了解一下图表的组成结构,一个简单的chart通常包括标题、绘图区、图例、数值(X)轴标题、数值(Y)轴标题,绘图区由N个数据系列组成。通过ChartWizard来生成图表非常的简单。网页“http://www.excelpx.com/home/show.aspx?id=3819&cid=15”对ChartWizard方法的参数有一个比较详细的介绍,在操作Excel时经常会用到一些枚举常量,对于这些枚举常量建议大家去这个网站搜一下“http://www.51testing.com/?72607/viewspace-155176”。
下面的代码演示了如何简单的通过ChartWizard非交互式的生成一个图表。当然了,你首先得要按照上一篇讲的方法新添加一些必要的类: _Chart、ChartObjects、ChartObject
// 变量的定义
_Application app;
Workbooks books;
_Workbook book;
Worksheets sheets;
_Worksheet sheet;
Range range;
LPDISPATCH lpDisp;
COleVariant vResult;
COleVariant
covTrue((short)TRUE),
covFalse((short)FALSE),
covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
//创建Excel 2003服务器(启动Excel)
if (!app.CreateDispatch(“Excel.Application”,NULL))
{
AfxMessageBox(“Create Excel service failure!”);
return;
}
// 设置为FALSE时,后面的app.Quit();注释要打开
// 否则EXCEL.EXE进程会一直存在,并且每操作一次就会多开一个进程
app.SetVisible(TRUE);
books.AttachDispatch(app.GetWorkbooks(),true);
book = books.Add(covOptional); // 添加一个工作簿,这里没有open操作,在最后调用SaveCopyAs另存为
// 得到Worksheets
sheets.AttachDispatch(book.GetWorksheets(),true);
// 得到Worksheet
sheet.AttachDispatch(sheets.GetItem(_variant_t((short)(1))));
// 得到全部Cells
range.AttachDispatch(sheet.GetCells(),true);
range.SetItem(_variant_t((LONG)1),_variant_t((LONG)1),_variant_t(“X”));
range.SetItem(_variant_t((LONG)1),_variant_t((LONG)2),_variant_t(“Y1”));
range.SetItem(_variant_t((LONG)1),_variant_t((LONG)3),_variant_t(“Y2”));
// 将数据填入Excel表格
for (int i = 0; i < 8; i++)
{
range.SetItem(_variant_t((LONG)(2+i)),_variant_t((LONG)1),_variant_t((long)(i+1)));
range.SetItem(_variant_t((LONG)(2+i)),_variant_t((LONG)2),_variant_t((long)((i+1)*(i+1))));
range.SetItem(_variant_t((LONG)(2+i)),_variant_t((LONG)3),_variant_t((long)((i+1)*2)));
}
// 图表(chart)
/*********************************************************************************/
double left = 200, top = 160, width = 450, height = 260;
_Chart chart;
ChartObjects chartobjects;
ChartObject chartobject;
lpDisp = sheet.ChartObjects(covOptional);
ASSERT(lpDisp);
chartobjects.AttachDispatch(lpDisp);
chartobject = chartobjects.Add(left, top, width, height);
chart.AttachDispatch(chartobject.GetChart());
chart.SetChartType(72); // xlXYScatterSmooth
lpDisp = sheet.GetRange(COleVariant(“B1”), COleVariant(“C9”));
ASSERT(lpDisp);
VARIANT var;
var.vt = VT_DISPATCH;
var.pdispVal = lpDisp;
chart.ChartWizard(var, // Source.
covOptional, // Gallery
covOptional, // Format: 1~6.
COleVariant((short)2), // PlotBy: 指定系列中的数据是来自行(1)还是来自列(2).
COleVariant((short)0), // CategoryLabels.
COleVariant((short)1), // SeriesLabels.
COleVariant((short)TRUE), // HasLegend.
COleVariant(“chart title”), // Title.
COleVariant(“XXX”), // CategoryTitle.
COleVariant(“YYY”), // ValueTitles.
covOptional // ExtraTitle.
);
book.SaveCopyAs(_variant_t(“E://test.xls”));
app.SetDisplayAlerts(false); // 不弹出对话框询问是否保存
// app.Quit(); // 退出
//释放对象
range.ReleaseDispatch();
sheet.ReleaseDispatch();
sheets.ReleaseDispatch();
book.ReleaseDispatch();
books.ReleaseDispatch();
app.ReleaseDispatch();
我们发现用ChartWizard生成的图表,它的X轴的选取就是它的数据区的左边的第一列数据,所以当我们要生成真正符合我们所需要的图表时,比如在一个chart中有4个系列,每一个系列都有自己所对应的X轴和Y轴,这时候用ChartWizard就不能达到我们的要求了,那怎么办?在下一篇文章当中我们将说一下如何在一个图表中生成分别具有自己所对应的X、Y轴的2个系列。
VC操作Excel之sercies、Trendline
http://blog.csdn.net/sp_daiyq/article/details/6193065
演示一下如何通过VC操作Excel生成下面这样的一个图表,它有两个系列,每个系列都拥有自己的X轴数据和Y轴数据,同时显示其线性的渐近线(TrendLine)以及获取其渐近线公式,因为在项目当中有时候需要其渐近线公式进行分析。
具体的代码演示如下:
[cpp] view plaincopyprint?
1.// 变量的定义
2._Application app;
3.Workbooks books;
4._Workbook book;
5.Worksheets sheets;
6._Worksheet sheet;
7.Range range;
8.LPDISPATCH lpDisp;
9.COleVariant vResult;
10.
11._Chart chart;
12.ChartObjects chartobjects;
13.ChartObject chartobject;
14.SeriesCollection serc;
15.Series sercies;
16.ChartTitle charttitle;
17.AxisTitle axistitle;
18.Axis axis;
19.
20.Trendlines trendlines;
21.Trendline trendline;
22.DataLabel dataLabel;
23.Font ft;
24.
25.VARIANT var;
26.CString str;
27.
28.COleVariant
29. covTrue((short)TRUE),
30. covFalse((short)FALSE),
31. covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
32.
33.//创建Excel 2003服务器(启动Excel)
34.if (!app.CreateDispatch(“Excel.Application”,NULL))
35.{
36. AfxMessageBox(“Create Excel service failure!”);
37. return;
38.}
39.
40.// 设置为FALSE时,后面的app.Quit();注释要打开
41.// 否则EXCEL.EXE进程会一直存在,并且每操作一次就会多开一个进程
42.app.SetVisible(TRUE);
43.books.AttachDispatch(app.GetWorkbooks(),true);
44.
45.book = books.Add(covOptional); // 添加一个工作簿,这里没有open操作,在最后调用SaveCopyAs另存为
46.
47.// 得到Worksheets
48.sheets.AttachDispatch(book.GetWorksheets(),true);
49.
50.// 得到Worksheet
51.sheet.AttachDispatch(sheets.GetItem(_variant_t((short)(1))));
52.
53.// 得到全部Cells
54.range.AttachDispatch(sheet.GetCells(),true);
55.
56.
57.range.SetItem(_variant_t((LONG)1),_variant_t((LONG)1),_variant_t(“X1”));
58.range.SetItem(_variant_t((LONG)1),_variant_t((LONG)2),_variant_t(“X2”));
59.range.SetItem(_variant_t((LONG)1),_variant_t((LONG)4),_variant_t(“Y1”));
60.range.SetItem(_variant_t((LONG)1),_variant_t((LONG)5),_variant_t(“Y2”));
61.
62.// 将数据填入Excel表格
63.for (int i = 0; i < 8; i++)
64.{
65. range.SetItem(_variant_t((LONG)(2+i)),_variant_t((LONG)1),_variant_t((long)(i+1)));
66. range.SetItem(_variant_t((LONG)(2+i)),_variant_t((LONG)2),_variant_t((long)(i+3)));
67.
68. range.SetItem(_variant_t((LONG)(2+i)),_variant_t((LONG)4),_variant_t((long)((i+1)*(i+1))));
69. range.SetItem(_variant_t((LONG)(2+i)),_variant_t((LONG)5),_variant_t((long)((i+1)*(i+2))));
70.}
71.
72.// 图表(chart)
73./******************************************************************************************/
74.double left = 200, top = 160, width = 450, height = 260;
75.
76.lpDisp = sheet.ChartObjects(covOptional);
77.ASSERT(lpDisp);
78.chartobjects.AttachDispatch(lpDisp);
79.
80.chartobject = chartobjects.Add(left, top, width, height);
81.chart.AttachDispatch(chartobject.GetChart());
82.chart.SetChartType(74); // xlXYScatterLines = 74
83.
84.var.vt = VT_DISPATCH;
85.
86.// 系列1 A
87./***********************************************************************/
88.serc = chart.SeriesCollection(covOptional);
89.sercies = serc.NewSeries();
90.
91.lpDisp = sheet.GetRange(_variant_t(“A2”), _variant_t(“A9”));
92.var.pdispVal = lpDisp;
93.sercies.SetXValues(var); // 设置X轴的数据
94.
95.lpDisp = sheet.GetRange(_variant_t(“D2”), _variant_t(“D9”));
96.var.pdispVal = lpDisp;
97.sercies.SetValues(var); // 设置Y轴的数据
98.sercies.SetName(“A”);
99.
100.// 添加趋势线
101.trendlines = sercies.Trendlines(covOptional);
102.trendline = trendlines.Add(-4132, covOptional, covOptional, covOptional, covOptional, covOptional,
103. _variant_t((long)1), _variant_t((long)0), covOptional); // xlDataSeriesLinear = -4132
104.
105.dataLabel = trendline.GetDataLabel();
106.ft = dataLabel.GetFont();
107.ft.SetColorIndex(_variant_t((long)5)); // blue
108.str = dataLabel.GetText(); // 获取趋势线的公式
109.
110.// 系列2 B
111./***********************************************************************/
112.serc = chart.SeriesCollection(covOptional);
113.sercies = serc.NewSeries();
114.
115.lpDisp = sheet.GetRange(_variant_t(“B2”), _variant_t(“B9”));
116.var.pdispVal = lpDisp;
117.sercies.SetXValues(var); // 设置X轴的数据
118.
119.lpDisp = sheet.GetRange(_variant_t(“E2”), _variant_t(“E9”));
120.var.pdispVal = lpDisp;
121.sercies.SetValues(var); // 设置Y轴的数据
122.sercies.SetName(“B”);
123.
124.// 添加趋势线
125.trendlines = sercies.Trendlines(covOptional);
126.trendline = trendlines.Add(-4132, covOptional, covOptional, covOptional, covOptional, covOptional,
127. _variant_t((long)1), _variant_t((long)0), covOptional); // xlDataSeriesLinear = -4132
128.
129.dataLabel = trendline.GetDataLabel();
130.ft = dataLabel.GetFont();
131.ft.SetColor(_variant_t((long)0xEE00EE));
132.str = dataLabel.GetText(); // 获取趋势线的公式
133.
134.chart.Location(2, _variant_t(“Sheet1”));
135.chart.SetHasTitle(TRUE);
136.
137.// 设置图表标题
138.charttitle = chart.GetChartTitle();
139.charttitle.SetText(“图表标题”);
140.
141.// 设置X坐标轴
142.axis = chart.Axes(_variant_t((long)1), 1);
143.axis.SetHasTitle(TRUE); // 设置坐标轴的标题可见
144.axistitle = axis.GetAxisTitle();
145.axistitle.SetText(“X轴标题”); // 设置X坐标轴的标题文本
146.
147.// 设置Y坐标轴
148.axis = chart.Axes(_variant_t((long)2), 1);
149.axis.SetHasTitle(TRUE); // 设置坐标轴的标题可见
150.axistitle = axis.GetAxisTitle();
151.axistitle.SetText(“Y轴标题”); // 设置Y坐标轴的标题文本
152.
153.
154.book.SaveCopyAs(_variant_t(“E://test.xls”));
155.app.SetDisplayAlerts(false); // 不弹出对话框询问是否保存
156.// app.Quit(); // 退出
157.
158.//释放对象
159.range.ReleaseDispatch();
160.sheet.ReleaseDispatch();
161.sheets.ReleaseDispatch();
162.book.ReleaseDispatch();
163.books.ReleaseDispatch();
164.app.ReleaseDispatch();