1.新建对话框程序,点击项目->添加类->TypeLib中的MFC类
选择注册表->Microsoft Excel 15.0 Object Library
如果选择的是文件,如果装的是32位的office,文件路径就是C:\Program Files (x86)\Microsoft Office\Office15\EXECEL.exe;如果装的是64位的office,那就在C:\Program Files\...文件夹下。
然后添加7个类:_Application,_Workbook,_Worksheet,Range,Workbooks,Worksheets,Font。添加完后点击完成,项目中多了7个头文件。
在 stdafx.h文件中加入#include "excel.h"
如果出现大量重定义变量, 打开excel.h文件,加入#ifndef ... #define .. #endif
2.点击编译会出现DialogBox的错误,点进去,将DialogBox修改该为_DialogBox。错误就消失了。
3.在**App的InitInstance()函数中添加
ConInitialize(0);
在ExitInstance()函数中添加
CoUnInitialize();
4.本程序是将一个excel文件读取到txt文件中,和将txt文件中的内容读取到excel文件中。
操作excel的程序写在一个线程中。
将excel文件内容写入txt文件中
// 读取Excel文件内容到txt文件中
DWORD CALLBACK ReadExcelToTxt(LPVOID lpParam)
{
CApplication app;
CWorkbook book;
CWorkbooks books;
CWorksheet sheet;
CWorksheets sheets;
CRange range;
CRange iCell;
LPDISPATCH lpDisp;
COleVariant vResult;
COleVariant covOptional((long)DISP_E_PARAMNOTFOUND,VT_ERROR);
if(!app.CreateDispatch(_T("Excel.Application")))
{
CString strMsg;
strMsg.Format(_T("无法创建Excel应用 . %d"),GetLastError());
MessageBox(NULL,strMsg,_T("tip"),MB_OK | MB_ICONINFORMATION);
return 0;
}
books.AttachDispatch(app.get_Workbooks());
lpDisp = books.Open(g_strExcelPath,covOptional,covOptional,covOptional,covOptional,covOptional,covOptional,covOptional,covOptional,covOptional,covOptional,covOptional,covOptional,covOptional,covOptional);
// 得到Workbook
book.AttachDispatch(lpDisp);
// 得到Worksheets
sheets.AttachDispatch(book.get_Worksheets());
// 得到当前活跃sheet
// 如果有单元格正处于编辑状态中,此操作不能返回,会一直等待
lpDisp = book.get_ActiveSheet();
sheet.AttachDispatch(lpDisp);
range = sheet.get_UsedRange();
range = range.get_Rows();
long lUsedRow = range.get_Count(); // 已经使用的最大行
range = sheet.get_UsedRange();
range = range.get_Columns();
long lUsedColumn = range.get_Count(); // 已经使用的最大列
CFile file;
if(!file.Open(g_strTxtPath,CFile::modeNoTruncate |CFile::modeCreate | CFile::modeWrite))
{
CString strMsg;
strMsg.Format(_T("打开文件%s失败 , %d"),g_strTxtPath,GetLastError());
MessageBox(NULL,strMsg,_T("tip"),MB_OK | MB_ICONINFORMATION);
return 0;
}
for(long r=1;r<=lUsedRow;r++)
{
CString cstraData;
for(long c=1;c<=lUsedColumn;c++)
{
// 循环读取值
range.AttachDispatch(sheet.get_Cells());
range.AttachDispatch(range.get_Item(COleVariant(r),COleVariant(c)).pdispVal);
vResult = range.get_Value2();
CString strValue;
switch(vResult.vt)
{
case VT_BSTR:
strValue = vResult.bstrVal;
break;
case VT_R8:
strValue.Format(_T("%f"),vResult.dblVal);
break;
default:
strValue = vResult.bstrVal;
}
cstraData += strValue+_T("\t");
}
cstraData += _T("\n");
char *strbuf = UnicodeToAnsic(cstraData);
file.SeekToEnd();
file.Write(strbuf,strlen(strbuf));
if(strbuf)
delete[] strbuf;
}
books.Close();
app.Quit();
file.Close();
// 释放对象
range.ReleaseDispatch();
sheet.ReleaseDispatch();
sheets.ReleaseDispatch();
book.ReleaseDispatch();
books.ReleaseDispatch();
app.ReleaseDispatch();
//MessageBox(NULL,_T("Done"),_T("Tip"),MB_OK | MB_ICONINFORMATION);
return 0;
}
将txt文件中内容读取到excel文件中,读取方式是。每正行读取txt文件,遇到空格取新一列。
// 将txt文件内容写入到excel文件中
DWORD CALLBACK WriteTxtToExcel(LPVOID lpParam)
{
CApplication app;
CWorkbook book;
CWorkbooks books;
CWorksheet sheet;
CWorksheets sheets;
CRange range;
CRange iCell;
COleVariant vResult;
COleVariant covOptional((long)DISP_E_PARAMNOTFOUND,VT_ERROR);
if(!app.CreateDispatch(_T("Excel.Application"),NULL))
{
CString strMsg;
strMsg.Format(_T("无法创建Excel应用 . %d"),GetLastError());
MessageBox(NULL,strMsg,_T("tip"),MB_OK | MB_ICONINFORMATION);
return 0;
}
FILE *fp = fopen(UnicodeToAnsic(g_strTxtPath),"r");
if(NULL == fp)
{
CString strMsg;
strMsg.Format(_T("无法打开文件%s . %d"),g_strTxtPath,GetLastError());
MessageBox(NULL,strMsg,_T("Tip"),MB_OK | MB_ICONINFORMATION);
return 0;
}
app.put_Visible(TRUE);
books.AttachDispatch(app.get_Workbooks(),TRUE); // 用来锁定对应的工作簿
//book.AttachDispatch(books.Add((COleVariant)TempPath),TRUE); // 加载Excel模板
book.AttachDispatch(books.Add(COleVariant((_bstr_t)CString().AllocSysString())));
sheets.AttachDispatch(book.get_Sheets(),TRUE);
sheet.AttachDispatch(sheets.get_Item(COleVariant((long)1)),TRUE); // 获取第一个Sheet
//sheet.put_Name(_T("TestSheet")); // 修改第1个页面的名字
// 设置表格内容
range.AttachDispatch(sheet.get_Cells(),TRUE); // 加载所有单元格
CString cstrBuf = _T("");
char strbuf[1024] = { 0 };
char substr[1024] = { 0 };
wchar_t wsubstr[1024] = { 0 };
int nRow = 1;
int nCol = 1;
while(fgets(strbuf,1024,fp))
{
nCol = 1;
int nPos = 0;
while(true)
{
TrimStr(strbuf,nPos);
nPos = FindChar(strbuf,' ');
if(nPos < 0)
{
GetSubStr(strbuf,0,strlen(strbuf),substr);
if(IsStrEmpty(strbuf)) break;
AnsicToUnicode(substr,wsubstr);
range.put_Item(COleVariant((long)nRow),COleVariant((long)nCol),COleVariant(wsubstr));
break;
}
GetSubStr(strbuf,0,nPos,substr);
if(IsStrEmpty(strbuf)) continue;
AnsicToUnicode(substr,wsubstr);
range.put_Item(COleVariant((long)nRow),COleVariant((long)nCol),COleVariant(wsubstr));
nCol++;
}
memset(strbuf,0,sizeof(strbuf));
nRow++;
}
//range.put_WrapText(_variant_t((long)1)); // 设置单元格内的文本为自动换行
//range.put_HorizontalAlignment(_variant_t((long)-4108)); // 默认=1,居中=-4108,左=-4131,右=-4152
//range.put_VerticalAlignment(_variant_t((long)-4108));
fclose(fp);
book.SaveCopyAs(COleVariant(g_strExcelPath));
book.put_Saved(TRUE);
books.Close();
app.Quit();
// 释放对象
range.ReleaseDispatch();
sheet.ReleaseDispatch();
sheets.ReleaseDispatch();
book.ReleaseDispatch();
books.ReleaseDispatch();
//MessageBox(NULL,_T("Done"),_T("Tip"),MB_OK | MB_ICONINFORMATION);
return 0;
}
5.运行结果
excel文件读取到txt文件
txt文件读取到excel文件
6.结论:在写入excel表格时,不能进行内存操作,一次性不能写入太大量的数据(除非是写入常量),否则会出现内存崩溃的错误。