vc读写excel

 

整理了下网上的方法

 

工程设置
工程 - 属性 - 常规 - MFC的使用 在静态库中使用MFC
工程 - 属性 - 常规 - 字符集    使用多字节字符集

 

#include <iostream>
#include "excel9.h"

using namespace std;
using namespace excel;


#ifdef WIN32
#define uint8_t  unsigned __int8
#define uint16_t unsigned __int16
#define uint32_t unsigned __int32
#define uint64_t unsigned __int64

#define int8_t  __int8
#define int16_t __int16
#define int32_t __int32
#endif
// 4-11
int unicode_to_utf8(uint16_t *in, int insize, uint8_t **out)
{
	int i = 0;
	int outsize = 0;
	int charscount = 0;
	uint8_t *result = NULL;
	uint8_t *tmp = NULL;

	charscount = insize / sizeof(uint16_t);
	result = (uint8_t *)malloc(charscount * 3 + 1);
	memset(result, 0, charscount * 3 + 1);
	tmp = result;

	for (i = 0; i < charscount; i++)
	{
		uint16_t unicode = in[i];

		if (unicode >= 0x0000 && unicode <= 0x007f)
		{
			*tmp = (uint8_t)unicode;
			tmp += 1;
			outsize += 1;
		}
		else if (unicode >= 0x0080 && unicode <= 0x07ff)
		{
			*tmp = 0xc0 | (unicode >> 6);
			tmp += 1;
			*tmp = 0x80 | (unicode & (0xff >> 2));
			tmp += 1;
			outsize += 2;
		}
		else if (unicode >= 0x0800 && unicode <= 0xffff)
		{
			*tmp = 0xe0 | (unicode >> 12);
			tmp += 1;
			//test 4-11
			*tmp =  0x80 | ( (unicode >> 6) & 0x3f );//0x80 | (unicode >> 6 & 0x00ff);
			tmp += 1;
			*tmp =  0x80 | ( unicode & 0x3f );//0x80 | (unicode & (0xff >> 2));
			tmp += 1;
			outsize += 3;
		}

	}

	*tmp = '\0';
	*out = result;
	return 0;
}


//从excel中读取数据
int readExcel(string g_strFileName)
{
	_Application l_MyExcelApp;
	_Workbook l_MyBook;
	Worksheets l_Mysheets;
	_Worksheet l_Mysheet;
	Workbooks l_MyBooks;
	try
	{
		//读取excel的类
		
		//需要初始化ole
		::CoInitialize(0);
		if (!l_MyExcelApp.CreateDispatch("Excel.Application",NULL))
		{
			
			return(0);
		}

		l_MyExcelApp.SetDisplayAlerts(false);
		l_MyBooks.AttachDispatch(l_MyExcelApp.GetWorkbooks(),TRUE);
		LPDISPATCH pBook = l_MyBooks.Open(g_strFileName.c_str(),
			vtMissing,vtMissing,vtMissing,vtMissing,vtMissing,vtMissing,
			vtMissing,vtMissing,vtMissing,vtMissing,vtMissing,vtMissing);
		if (pBook == NULL)
		{
			
			return(0);
		}

		l_MyBook.AttachDispatch(pBook);
		l_Mysheets.AttachDispatch(l_MyBook.GetWorksheets(),TRUE);
		long SheetCnt = l_Mysheets.GetCount();
		for (long iSheet = 0; iSheet < SheetCnt; iSheet++)
		{
			l_Mysheet.AttachDispatch(l_Mysheets.GetItem(_variant_t(iSheet+1)));
			Range usedRange;
			usedRange.AttachDispatch(l_Mysheet.GetUsedRange());
			Range rangeRow;
			rangeRow.AttachDispatch(usedRange.GetRows());
			long maxRows = rangeRow.GetCount();
			Range rangeCol;
			rangeCol.AttachDispatch(usedRange.GetColumns());
			long maxCols = rangeCol.GetCount();
			//最少一行,最少六列
			if(iSheet == 0 &&  (maxRows < 1 ))
			{
				
				break;
			}

			if (maxCols < 6)
			{
				
				continue;
			}
			//读取数据文件
			Range Cells;
			Cells.AttachDispatch(l_Mysheet.GetCells());  
			char strTmp[256] = {0};
			for (long iRow = 0; iRow < maxRows; iRow++)
			{
				
				for (long iCol=0; iCol<6;iCol++)
				{				
					string strValue("");
					Range Cell;
					Cell.AttachDispatch(Cells.GetItem (COleVariant((long)iRow+1),COleVariant((long)iCol+1)).pdispVal);
					_variant_t vResult;
					vResult.lVal = 0;
					//此处加false是为了避免内存泄露
					vResult=_variant_t(Cell.GetValue(), false);
					if(vResult.vt == VT_BSTR) // 字符串
					{
						strValue = (_bstr_t)vResult.bstrVal;

						/*
						//从excel中读取的字符是wchar类型的unicode字符,使用GB2312ToUTF_8进行转换
						//有问题,不能把韩文等字符转换为UTF8编码,会出现乱码,
						//使用unicode_to_utf8来进行转换
						uint8_t *utf8 = NULL;
						wchar_t WStr[1024];
						wcscpy(WStr, (_bstr_t)vResult.bstrVal);
						unicode_to_utf8((unsigned short*)WStr, sizeof(WStr), &utf8);
						ExcelCell.strSms = (char*)utf8;
						free(utf8);
						*/
					}
					//added by Sunday
					else if (vResult.vt == VT_DATE) //date
					{
						DATE   dt   =   vResult.date; 
						COleDateTime   odt   =   COleDateTime(dt); 
						CString   str; 
						str   =   odt.Format( "%Y-%m-%d %H:%M:%S");
						strValue = str.GetBuffer();
					}
					else if (vResult.vt == VT_R8) //int 
					{
						sprintf(strTmp, "%0.f", vResult.dblVal);
						strValue = strTmp;
					}
					//added end
					else// 其他
					{
						strValue="";
					}  
					if (iCol == 0)
					{
					}

				}
				
			}
		}
		
		


	}
	catch (CException* e)
	{

	}

endOfWhile:
	l_MyBook.Close(_variant_t(long(FALSE)),vtMissing,vtMissing);
	l_Mysheet.ReleaseDispatch();
	l_Mysheets.ReleaseDispatch();
	l_MyBook.ReleaseDispatch();
	l_MyBooks.Close();
	l_MyBooks.ReleaseDispatch();
	l_MyExcelApp.Quit();
	l_MyExcelApp.ReleaseDispatch();
	//释放
	::CoUninitialize();

	return 0;
}



void setExcelTitle(excel::Range& range)
{
	int row = 1;
	range.SetItem(_variant_t(row),_variant_t((long)1),_variant_t("1"));
	range.SetItem(_variant_t(row),_variant_t((long)2),_variant_t("2"));
	range.SetItem(_variant_t(row),_variant_t((long)3),_variant_t("3"));
	range.SetItem(_variant_t(row),_variant_t((long)4),_variant_t("4"));
	range.SetItem(_variant_t(row),_variant_t((long)5),_variant_t("5"));
	range.SetItem(_variant_t(row),_variant_t((long)6),_variant_t("6"));
}


int DeleteExcelSheet(CString strSheetName, excel::Worksheets& sheets)  
{  
	int             i;  
	int             nNofSheet;  
	CString         strInfo;  

	excel::_Worksheet sheet;

	nNofSheet = sheets.GetCount();  
	for (i = 1; i <= nNofSheet; i++)  
	{  
		// nSheetIndex: base on 1  
		sheet.AttachDispatch(sheets.GetItem(COleVariant(long(i))));  
		strInfo = sheet.GetName();  
		if (strInfo == strSheetName)  
		{  
			sheet.Delete();  
			return TRUE;  
		}  
	}  

	return FALSE;//cannot find the target sheet  
}

#define XLS_LEFT    (-4131)  
#define XLS_MID     (-4108)  
#define XLS_RIGHT   (-4152)

static COleVariant covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);

int SetExcelAlignment(int nStartRow, int nStartCol, int nEndRow,int nEndCol,  
					  int nHorizontal /*=XLS_MID*/, excel::_Worksheet& sheet)   
{ 
	excel::Range range;
	range.AttachDispatch(sheet.GetCells()); 
	excel::Range iCell;
	iCell.AttachDispatch(range.GetItem(COleVariant(long(nStartRow)),COleVariant(long(nStartCol))).pdispVal);  
	iCell.AttachDispatch(iCell.GetResize(COleVariant(long(nEndRow)),COleVariant(long(nEndCol))));  
	iCell.SetHorizontalAlignment(COleVariant(long(nHorizontal)));  

	return 1;  
}  

int SetColumnWidth(excel::_Worksheet& sheet, int nRow, int nCol,long nWidth)  
{  
	excel::Range range;
	excel::Range iCell;
	range.AttachDispatch(sheet.GetCells());  
	iCell.AttachDispatch(range.GetItem(COleVariant(long(nRow)),COleVariant(long(nCol))).pdispVal);  
	iCell.SetColumnWidth(COleVariant(long(nWidth)));  

	return TRUE;  
}


#define MAX_ROW_OF_ONE_EXCELSHEET 200000

long copyFile(const char* from, const char* to)
{

	char cmd[1024] = {0};
	//sprintf(cmd, "copy %s\\%s %s", g_exePath.c_str(), from, to);
	sprintf(cmd, "copy %s %s", from, to);
	system(cmd);

	cout << "copy done,  " << cmd << endl;
	return 0;
}


long writeToExcel(const char* fileName)
{

	long begin = 1;
	long sum = 0;
	copyFile(".\\sample.xlsx", fileName);

	excel::_Application     ExcelApp; 
	excel::Workbooks      wbsMyBooks; 
	excel::_Workbook      wbMyBook; 
	excel::Worksheets     wssMysheets; 
	excel::_Worksheet     wsMysheet; 
	excel::Range              rgMyRge;


	if (::CoInitialize( NULL ) == E_INVALIDARG)
	{
		
		return -1;
	}

	try
	{

		if (!ExcelApp.CreateDispatch((LPCTSTR)"Excel.Application", NULL)) 
		{ 
			
			return -2; 
		} 

		ExcelApp.SetVisible(false); //将excel设置为隐藏状态,防止vc在写入时受到人为干扰
		ExcelApp.SetDisplayFullScreen(false);
		ExcelApp.SetDisplayAlerts(false);//屏蔽vc关闭excel时跳出的保存对话框

		wbsMyBooks.AttachDispatch(ExcelApp.GetWorkbooks(),true); 

		//fileName = "D:\\09\\10\\test.xlsx";
		char path[256] = {0};
		strcpy(path, fileName);

		wbMyBook.AttachDispatch(wbsMyBooks.Add(_variant_t(path)));//fileName

		//得到Worksheets 
		wssMysheets.AttachDispatch(wbMyBook.GetWorksheets(),true);
		//得到sheet1 
		//wsMysheet.AttachDispatch(wssMysheets.GetItem(_variant_t("Sheet1")),true);
		wsMysheet.AttachDispatch(wssMysheets.GetItem(COleVariant(long(1))), true);
		wsMysheet.SetVisible(true);


		rgMyRge.AttachDispatch(wsMysheet.GetCells(),true); 
		setExcelTitle(rgMyRge);
		//rgMyRge.AutoFit();


		CString strSheetName = "Sheet2";
		long row = 2;
		//rgMyRge.SetItem(_variant_t(row),_variant_t((long)1),_variant_t("tttttttttttttt"));
		 
		//loop to write excel file
		if (1) //判断文件是否读结束
		{
			if (1)
			{
				for (int ic = 0; ic < 9; ic++)
				{
					sum++;
					//rgMyRge.SetItem(_variant_t(row),_variant_t((long)1),_variant_t("tttttttttttttt"));
					//write the new sheet
					if (sum > 1 && ((sum - 1 ) % MAX_ROW_OF_ONE_EXCELSHEET == 0))
					{
						char sheetName[256] = {0};
						sprintf(sheetName, "第%d条—第%d条", begin, sum - 1);
						wsMysheet.SetName(sheetName);
						begin += MAX_ROW_OF_ONE_EXCELSHEET;

						SetExcelAlignment(2, 1, MAX_ROW_OF_ONE_EXCELSHEET+2, 7, XLS_LEFT, wsMysheet);

						SetColumnWidth(wsMysheet, 1, 1, 15);
						SetColumnWidth(wsMysheet, 1, 2, 15);
						SetColumnWidth(wsMysheet, 1, 3, 15);
						SetColumnWidth(wsMysheet, 1, 4, 15);
						SetColumnWidth(wsMysheet, 1, 5, 15);
						//SetColumnWidth(wsMysheet, 1, 6, 300);

						//find the Sheet2, add a new sheet before it
						int nNofSheet = wssMysheets.GetCount(); 

						for (int i = 1; i <= nNofSheet; i++)  
						{  
							// nSheetIndex: base on 1  
							wsMysheet.AttachDispatch(wssMysheets.GetItem(COleVariant(long(i))));  
							CString strInfo = wsMysheet.GetName();  
							if (strInfo == strSheetName)  
							{  
								wsMysheet.Activate(); 
								break;
							}
						}

						//add a sheet
						wssMysheets.Add(vtMissing, covOptional, covOptional, covOptional);//add sheet  
						wsMysheet.AttachDispatch(wbMyBook.GetActiveSheet());  
						wsMysheet.SetName("sheet1");

						rgMyRge.AttachDispatch(wsMysheet.GetCells(),true); 
						setExcelTitle(rgMyRge);

						row = 2;

					}

					//write data in row, column 
					rgMyRge.SetItem(_variant_t(row),_variant_t((long)1),_variant_t("str value"));
					rgMyRge.SetItem(_variant_t(row),_variant_t((long)2),_variant_t("str value"));
					rgMyRge.SetItem(_variant_t(row),_variant_t((long)3),_variant_t("str value"));
					rgMyRge.SetItem(_variant_t(row),_variant_t((long)4),_variant_t("str value"));
					rgMyRge.SetItem(_variant_t(row),_variant_t((long)5),_variant_t("str value"));
					rgMyRge.SetItem(_variant_t(row),_variant_t((long)6),_variant_t("str value"));

					row++;
				}
			}
			else
			{
				
			}


		}
		///
		char sheetName[256] = {0};
		if (sum == 0)
		{
			begin = 0;
		}
		sprintf(sheetName, "第%d条—第%d条", begin, sum);

		//set the name of the sheet
//		wsMysheet.SetName(sheetName);

		SetExcelAlignment(2, 1, sum%MAX_ROW_OF_ONE_EXCELSHEET+2, 7, XLS_LEFT, wsMysheet);

		SetColumnWidth(wsMysheet, 1, 1, 15);
		SetColumnWidth(wsMysheet, 1, 2, 15);
		SetColumnWidth(wsMysheet, 1, 3, 15);
		SetColumnWidth(wsMysheet, 1, 4, 15);
		SetColumnWidth(wsMysheet, 1, 5, 15);
		//SetColumnWidth(wsMysheet, 1, 6, 300);


		//delete the sheet2 and sheet3 
		DeleteExcelSheet(strSheetName, wssMysheets);
		strSheetName = "Sheet3";
		DeleteExcelSheet(strSheetName, wssMysheets);

		wsMysheet.SaveAs(path, vtMissing,vtMissing,vtMissing,vtMissing,
			vtMissing,vtMissing,vtMissing,vtMissing);//相当于excel菜单的保存 fileName
	}
	catch (CMemoryException* e)
	{

	}
	catch (COleDispatchException* e)
	{
		cout << e->m_strDescription << endl;	
	}
	catch (CException* e)
	{
	}
	catch(_com_error &e)
	{
		cout << (e.Description());

	}
	catch (...)
	{

	}

	// wbMyBook.SaveCopyAs(_variant_t(strPath)); //相当于excel菜单的另存为
	// int ty=MessageBox("关闭EXCEL","", MB_ICONERROR | MB_YESNOCANCEL);
	//ExcelApp.SetVisible(true);


	//wbMyBook.PrintPreview(_variant_t(false)); 
	//释放对象 
	rgMyRge.ReleaseDispatch(); 
	wsMysheet.ReleaseDispatch(); 
	wssMysheets.ReleaseDispatch(); 
	wbMyBook.ReleaseDispatch(); 
	wbsMyBooks.ReleaseDispatch(); 

	ExcelApp.Quit();///要想彻底关闭excel进程,必须把ExcelApp.Quit();放在ExcelApp.ReleaseDispatch();之前
	ExcelApp.ReleaseDispatch();// 

	::CoUninitialize();

	return 0;
}


int main()
{
	cout << "hello " << endl;
//	readExcel("D:\\09\\testExcel\\test.xlsx");

	//test write
	writeToExcel("D:\\09\\testExcel\\write.xlsx");

	return 0;
}


 

 

【前言】 工作或学习中可能需要实现基于VC读\写Excel文件的功能,本人最近也遇到了该问题。中间虽经波折,但是最终还是找到了解决问题的办法。 在此跟大家分享,希望对跟我同样迷茫过的同学们有所帮助。 1、程序功能 1)打开一个excel文件; 2)显示到CListCtrl上; 3)新建一个Excel文件。 以上均在对话框中实现。 2、平台 VC++2010 3、实现方法 常用的Excel打开方式有两种 1)通过数据库打开; 2)OLE方式打开。 由于方式1)操作繁琐,经常出现莫名的错误,这里选用方式2). 4、准备步骤 首先新建一个Dialog窗体程序,添加list control和两个按钮 1)将ExcelLib文件夹拷贝到程序目录下; 2)将Export2Excel.h,Export2Excel.cpp两个文件添加到项目; 3)包含头文件,#include "ExcelLib/Export2Excel.h" 通过以上步骤在程序中引入了可以读取Excle文件的CExport2Excel类; 5、打开excel文件 通过按钮点击打开 void CExcelTestDlg::OnBnClickedButtonOpenExcel() { //获取文件路径 CFileDialog* lpszOpenFile; CString szGetName; lpszOpenFile = new CFileDialog(TRUE,"","",OFN_FILEMUSTEXIST|OFN_HIDEREADONLY,"Excel File(*.xlsx;*.xls)|*.xls;*.xlsx",NULL); if (lpszOpenFile->DoModal()==IDOK) { szGetName = lpszOpenFile->GetPathName(); SetWindowText(szGetName); delete lpszOpenFile; } else return; //打开文件 //文件中包含多个sheet时,默认打开第一个sheet CExport2Excel Excel_example; Excel_example.OpenExcel(szGetName); //获取sheet个数 int iSheetNum = Excel_example.GetSheetsNumber(); //获取已使用表格行列数 int iRows = Excel_example.GetRowCount(); int iCols = Excel_example.GetColCount(); //获取单元格的内容 CString cs_temp = Excel_example.GetText(1,1); //AfxMessageBox(cs_temp); //List control上显示 //获取工作表列名(第一行) CStringArray m_HeadName; m_HeadName.Add(_T("ID")); for (int i=1;iGetItemCount()>0) { m_list.DeleteColumn(0); } //初始化ClistCtrl,加入列名 InitList(m_list,m_HeadName); //填入内容 //第一行是标题,所以从第2行开始 CString num; int pos; for (int row = 2;row<=iRows; row++) { pos = m_list.GetItemCount(); num.Format(_T("%d"),pos +1); m_list.InsertItem(pos,num); for (int colum=1;columDoModal()==IDOK) { szGetName = lpszOpenFile->GetPathName(); SetWindowText(szGetName); delete lpszOpenFile; } else return; //文件全名称 CString csFileName = szGetName; //需要添加的两个sheet的名称 CString csSheetName = "newSheet"; CString csSheetName2 = "newSheet2"; // 新建一个excel文件,自己写入文字 CExport2Excel Excel_example; //新建excel文件 Excel_example.CreateExcel(csFileName); //添加sheet,新加的sheet在前,也就是序号为1 Excel_example.CreateSheet(csSheetName); Excel_example.CreateSheet(csSheetName2); //操作最开始添加的sheet:(newSheet) Excel_example.SetSheet(2); //添加表头 Excel_example.WriteHeader(1,"第一列"); Excel_example.WriteHeader(2,"第二列"); //添加核心数据 Excel_example.WriteData(1,1,"数据1"); Excel_example.WriteData(1,2,"数据2"); //保存文件 Excel_example.Save(); //关闭文件 Excel_example.Close(); } 7、注意事项 1)一般单个Excel文件包含多个sheet,程序默认打开第一个; 2)指定操作sheet,使用Excel_example.SetSheet(2)函数; 3)打开文件时最左侧的sheet序号为1,新建excel时最新添加的sheet序号为1. 【后记】 本程序主要基于网络CSDN中---“Excel封装库V2.0”---完成,下载地址是:http://download.csdn.net/detail/yeah2000/3576494,在此表示感谢!同时, 1)在其基础上作了小改动,改正了几个小错误,添加了几个小接口; 2)添加了如何使用的例子,原程序是没有的; 3)详细的注释 发现不足之处,还请大家多多指教!
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值