VC/MFC实现写Excel文件

最近做了个保单系统,需要一些功能,比如查询的记录保存到制定的位置:

 

VC/MFC实现写Excel文件_第1张图片

 

VC/MFC实现写Excel文件_第2张图片

 

1、网上很多操作方式,很少可行,受不了于是乎,我自己研究了。

2、使用csv格式保存呗,使用windows自带的CFile和CStdioFile类,前者提供了write后者提供了writestring功能,简单的贴两个代码吧,但是这个使用的时候必须设置本地化:

void CDb_dialog::OnBnClickedButtonDbSave()
{
	// TODO: Add your control notification handler code here
	int ItemCount = m_list_ctrl.GetItemCount();
	int subnItemCount = m_list_ctrl.GetHeaderCtrl()->GetItemCount();

	if(!ItemCount || !subnItemCount)
	{
		return;
	}

	if(!this->file_path.GetLength()) //如果文件名为空,弹出对话框
	{
		static TCHAR BASED_CODE szFilter[] = _T("Datasheet Files (*.csv)|*.csv||");

		CFileDialog file(false, _T("csv"), _T("保单保存"), 6, szFilter);
		file.DoModal();

		this->file_path = file.GetPathName();
	}

	if(!this->file_path.GetLength()) //如果文件名为空,弹出对话框
	{
		return;
	}

	CStdioFile myFile;
	CFileException fileException;

	char* old_locale = _strdup( setlocale(LC_CTYPE,NULL) );

	setlocale( LC_CTYPE, "chs" );//设定

	if ( !myFile.Open( file_path.GetString(), 
		CFile::modeCreate| CFile::modeReadWrite, &fileException ) )
	{
		TCHAR szError[1024];
		fileException.GetErrorMessage(szError, 1024);

		MessageBox(szError);

		return;
	}

	//遍历所有行
	CString rowContent;
	CString subContent;
	for(int nItem = 0; nItem < ItemCount; nItem++)
	{
		for(int subnItem = 0; subnItem < subnItemCount - 1; subnItem++)
		{
			subContent = m_list_ctrl.GetItemText(nItem, subnItem);
			rowContent += subContent;
			rowContent += _T(",");
		}

		subContent = m_list_ctrl.GetItemText(nItem, subnItemCount - 1);
		rowContent += subContent;
		rowContent += _T("\n");

		myFile.WriteString(rowContent.GetString());
		myFile.Flush();

		rowContent.Empty();
	}

	setlocale( LC_CTYPE, old_locale );

	free( old_locale );//还原区域设定

	myFile.Close();
}


3、使用其他的库,我使用的是这个:http://www.codeproject.com/Articles/13852/BasicExcel-A-Class-to-Read-and-Write-to-Microsoft

这个上面提供了基本的使用例子,以及相应的类。

using namespace YExcel;

void CDb_dialog::OnBnClickedButtonDbSave()
{
	// TODO: Add your control notification handler code here
	int ItemCount = m_list_ctrl.GetItemCount();
	int subnItemCount = m_list_ctrl.GetHeaderCtrl()->GetItemCount();

	if(!ItemCount || !subnItemCount)
	{
		return;
	}

	if(!this->file_path.GetLength()) //如果文件名为空,弹出对话框
	{
		static TCHAR BASED_CODE szFilter[] = _T("Datasheet Files (*.xls)|*.xls||");

		CFileDialog file(false, _T("csv"), _T("保单保存"), 6, szFilter);
		file.DoModal();

		this->file_path = file.GetPathName();
	}

	if(!this->file_path.GetLength()) //如果文件名为空,弹出对话框
	{
		return;
	}

	BasicExcel e;
	e.New(1);
	e.RenameWorksheet("Sheet1", "Test1");
	BasicExcelWorksheet* sheet = e.GetWorksheet("Test1");
	BasicExcelCell* cell;

	if(!sheet)
	{
		return;
	}

	//遍历所有行
	CString rowContent;
	CString subContent;
	for(int nItem = 0; nItem < ItemCount; nItem++)
	{
		for(int subnItem = 0; subnItem < subnItemCount - 1; subnItem++)
		{
			subContent = m_list_ctrl.GetItemText(nItem, subnItem);
			if(subContent.GetLength())
			{
				cell = sheet->Cell(nItem, subnItem);
				cell->SetWString(subContent.GetString());
			}
		}
	}

	e.SaveAs("aa.xls");

	CopyFile(_T("aa.xls"), file_path.GetString(), false);
	int error_no = GetLastError();

}


最后使用了一个saveas到本地,然后copy到指定的目录,貌似这个库不支持非本地保存,没有深究,且这样吧。

 

最后截图保存的文件:

VC/MFC实现写Excel文件_第3张图片

 

这个文章先简单的描述一下了,还是推荐使用basicexcel这个库的。毕竟还是支持utf-16的操作。而且作者也给出了一个相应的实例,慢慢细心看,还是很简单的。

 

后续我在给出一些vc 2008通过odbc操作mysql的实例吧,具体就是使用CDatabase 和CRecordSet类做这个操作了。

 

你可能感兴趣的:(list,Excel,File,dialog,csv)