在用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个系列。
