在 Visual Studio 2008 中使用 C++ MFC 应用程序自动化 Excel 2007 并创建图表






4.89/5 (16投票s)
本文介绍如何使用 C++ MFC 应用程序自动化 Excel 2007 并创建图表。
引言
本文介绍如何使用 C++ MFC 应用程序自动化 Excel 2007。该解决方案也适用于 Excel 2010。我还重点介绍了完成此任务时遇到的一些问题。在本文中,我将介绍如何打开 Excel 应用程序,如何创建工作表并在工作表中输入数据,以及如何使用工作表中的数据创建图表。我使用 Visual Studio 2008 进行此项目,但我相信它也适用于 VS 2010。
使用代码
假设您已安装 Microsoft Excel 2007,请打开 Visual Studio 并创建一个名为 AutomateExcel 的新 MFC 应用程序。
选择应用程序类型为基于对话框,然后单击“完成”。
从“项目”菜单中单击“添加类”,然后选择“从 TypeLib 添加 MFC 类”。
在“从类型库添加类”向导中,选择“注册表”选项,然后从下拉列表中选择“Microsoft Excel 12.0 对象库<1.6>”。
选择以下接口
- _Application
- _Chart
- _Workbook
- _Worksheet
- Charts
- 字体
- Range
- Workbooks
- Worksheets
单击“完成”后,将创建所有相关的头文件。打开 *AutomateExcelDlg.cpp* 并包含所有这些头文件。
#include "CApplication.h"
#include "CFont0.h"
#include "CRange.h"
#include "CWorkbook.h"
#include "CWorkbooks.h"
#include "CWorksheet.h"
#include "CWorksheets.h"
#include "CChart.h"
#include "CCharts.h"
尝试在此处构建您的项目。您将在 *excel.tlh* 文件中收到大量错误。为了消除这些错误,您需要注释掉 Visual Studio 创建的所有头文件中的所有 #import
语句。您可以查找所有“#import
”,然后快速转到每个头文件并注释掉这些行。
//#import "C:\\Program Files\\Microsoft Office\\Office12\\EXCEL.EXE" no_namespace
...
注释掉所有 #import
语句并保存所有这些文件后,再次尝试构建您的项目。您将在文件 *crange.h* 的“VARIANT DialogBox()
”行中收到一些语法错误。解决此错误的关键是在 DialogBox()
前面加上下划线。
VARIANT _DialogBox()
...
再次构建以确保您的构建成功。现在我们准备编写一些代码
打开 *AutomateExcel.cpp* 文件,并在 InitInstance
函数中添加以下代码
if(!AfxOleInit())
{
AfxMessageBox(_T("Cannot initialize COM dll"));
return FALSE;
}
...
AfxEnableControlContainer();
从解决方案资源管理器中展开“资源文件”,然后双击 *AutomateExcel.rc*。在资源视图中,展开“对话框”文件夹,然后双击 IDD_AUTOMATEEXCEL_DIALOG
以打开应用程序的对话框页面。删除初始标签,也删除“取消”按钮。将“确定”按钮的标题更改为“运行”,并将 ID 重命名为 IDRUN。双击“运行”按钮以创建 OnBnClickedRun()
事件处理程序。将以下代码添加到此函数中
void CAutomateExcelDlg::OnBnClickedRun()
{
// Commonly used OLE variants.
COleVariant
covTrue((short)TRUE),
covFalse((short)FALSE),
covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
CApplication app;
// Start Excel and get an Application object.
if(!app.CreateDispatch(TEXT("Excel.Application")))
{
AfxMessageBox(TEXT("Couldn't start Excel and get Application object."));
return;
}
app.put_Visible(TRUE);
app.put_UserControl(TRUE);
}
构建解决方案并运行它。单击“运行”按钮,注意 Excel 应用程序打开。恭喜!您已成功完成您的第一个自动化任务 - 打开 Excel 应用程序。现在让我们在其中添加一个工作簿,并在工作簿的第一个工作表中添加一些信息。
if(!app.CreateDispatch(TEXT("Excel.Application")))
{
AfxMessageBox(TEXT("Couldn't start Excel and get Application object."));
return;
}
.
.
.
CWorkbooks books;
CWorkbook book;
CWorksheets sheets;
CWorksheet sheet;
CRange range;
CFont0 font;
books = app.get_Workbooks();
book = books.Add (covOptional);
//Get the first sheet.
sheets =book.get_Sheets();
sheet = sheets.get_Item(COleVariant((short)1));
range = sheet.get_Range(COleVariant(TEXT("A1")),COleVariant(TEXT("A1")));
range.put_Value2(COleVariant(TEXT("Average precipation (mm)")));
range = sheet.get_Range(COleVariant(TEXT("A1")),COleVariant(TEXT("C1")));
range.Merge(covOptional);
range = sheet.get_Range(COleVariant(TEXT("B2")),COleVariant(TEXT("B2")));
range.put_Value2(COleVariant(TEXT("Acapulco")));
range = sheet.get_Range(COleVariant(TEXT("C2")),COleVariant(TEXT("C2")));
range.put_Value2(COleVariant(TEXT("Amsterdam")));
//Fill A3:A6 with an array of values (Months).
COleSafeArray saRet;
DWORD numElements[]={4,1}; //4x1 element array
saRet.Create(VT_BSTR, 2, numElements);
FillSafeArray(L"January", 0, 0, &saRet);
FillSafeArray(L"April", 1, 0, &saRet);
FillSafeArray(L"July", 2, 0, &saRet);
FillSafeArray(L"October", 3, 0, &saRet);
range = sheet.get_Range(COleVariant(TEXT("A3")), COleVariant(TEXT("A6")));
range.put_Value2(COleVariant(saRet));
saRet.Detach();
//Fill B3:C6 with values
range = sheet.get_Range(COleVariant(TEXT("B3")),COleVariant(TEXT("B3")));
range.put_Value2(COleVariant(short(10)));
range = sheet.get_Range(COleVariant(TEXT("B4")),COleVariant(TEXT("B4")));
range.put_Value2(COleVariant(short(69)));
range = sheet.get_Range(COleVariant(TEXT("B5")),COleVariant(TEXT("B5")));
range.put_Value2(COleVariant(short(5)));
range = sheet.get_Range(COleVariant(TEXT("B6")),COleVariant(TEXT("B6")));
range.put_Value2(COleVariant(short(53)));
range = sheet.get_Range(COleVariant(TEXT("C3")),COleVariant(TEXT("C3")));
range.put_Value2(COleVariant(short(208)));
range = sheet.get_Range(COleVariant(TEXT("C4")),COleVariant(TEXT("C4")));
range.put_Value2(COleVariant(short(76)));
range = sheet.get_Range(COleVariant(TEXT("C5")),COleVariant(TEXT("C5")));
range.put_Value2(COleVariant(short(145)));
range = sheet.get_Range(COleVariant(TEXT("C6")),COleVariant(TEXT("C6")));
range.put_Value2(COleVariant(short(74)));
//Format A1:C1 as bold, vertical alignment = center.
range = sheet.get_Range(COleVariant(TEXT("A1")), COleVariant(TEXT("C1")));
font = range.get_Font();
font.put_Bold(covTrue);
range.put_VerticalAlignment(COleVariant((short)-4108)); //xlVAlignCenter = -4108
//AutoFit columns A:D.
range = sheet.get_Range(COleVariant(TEXT("A1")), COleVariant(TEXT("D1")));
CRange cols;
cols = range.get_EntireColumn();
cols.AutoFit();
.
.
.
app.put_Visible(TRUE);
app.put_UserControl(TRUE);
在这里,我们获取工作簿的第一个工作表,并通过使用范围将数据输入到其中。FillSafeArray
函数如下:
void FillSafeArray(OLECHAR FAR* sz, int iRow, int iCol,
COleSafeArray* sa)
{
VARIANT v;
long index[2];
index[0] = iRow;
index[1] = iCol;
VariantInit(&v);
v.vt = VT_BSTR;
v.bstrVal = SysAllocString(sz);
sa->PutElement(index, v.bstrVal);
SysFreeString(v.bstrVal);
VariantClear(&v);
}
现在让我们快速添加一个图表。
CCharts charts;
CChart chart;
charts = book.get_Charts();
chart = charts.Add(covOptional, covOptional, covOptional);
构建并运行项目。单击“运行”按钮。这是 Excel 2007 的外观。
图表是使用 Excel 2007 和 2010 中当前活动工作表中的数据创建的。此工作表是我们刚刚创建的工作表。图表还有很多可以做的事情,特别是当您想创建自己的图表来选择您的系列和轴时。但对于本文,我将保持简单并在此处结束。我将在以后的文章中尝试涵盖更多内容。
历史
版本 1.0