【MFC CListCtrl控件内容导出Excel/.csv文件】

【MFC C.ListCtrl控件内容导出Excel/.csv文件】


1.使用工具:vs2017,excel。
因为新版的Viusual Studio想要在已下载Visual C++框架的基础上添加新类需要在菜单栏的->项目->添加新项中进行(和旧版不同)
在这里插入图片描述
2.在Typelib中的MFC类这一类型库中添加相关类和接口
在这里插入图片描述
由于我一开始选择的是wps office,注册表默认选择的是wps下的etapi的路径(但是好像没有接口,所以无奈选择了excel):
在这里插入图片描述
3.导入excel.exe的路径,这样子就能选择接口了
在这里插入图片描述
在这里我们选择:
Application
Range
Workbooks
Worksheets
Workbook
Worksheet
这6个接口类(具体的阐述和定义请查阅Microsoft相关接口文档,这里良心附个文档链接:https://learn.microsoft.com/zh-cn/office/vba/api/excel.workbook,毕竟我不是很喜欢网络上很多模棱两可讲了和没讲似的文章…)
4.导入工程类会报错,先别急, 注释掉6个类文件开头的#import “C:\Program Files\Microsoft Office\root\Office16\EXCEL.EXE” no_namespace
我的接口类函数中的DISPATCH_PROPERTYGET总会显示未定义标识符,但是不影响我功能的运行,如果有了解的懂哥还请不吝赐教!
5.把你添加的这六个类都include到你要实现该功能的类中去
#include “CApplication.h”
#include “CRange.h”
#include “CWorkbooks.h”
#include “CWorksheets.h”
#include “CWorkbook.h”
#include “CWorksheet.h”
6.然后在对应类中的函数进行这个数据表数据的读取,文件类型的选择和读取就行了。
网上有许多类似相关的代码:

CFileDialog FileDialog(FALSE, _T("*.xls"), NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, _T("Microsoft Excel 2000(*.xls)|*.xls|所有文件(*.*)"), this);
	if (FileDialog.DoModal() != IDOK)
	{
		return;
	}
	CString cStrFile = FileDialog.GetPathName();  //选择保存路径名称

	if (::PathFileExists(cStrFile))
		DeleteFile(cStrFile);

	//CString cStrFile = _T("E:\\myexcel.xls");
	COleVariant covTrue((short)TRUE), covFalse((short)FALSE), covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);

	CApplication app; //Excel程序
	CWorkbooks books; //工作簿集合
	CWorkbook book;  //工作表
	CWorksheets sheets;  //工作簿集合
	CWorksheet sheet; //工作表集合
	CRange range; //使用区域

	CoUninitialize();

	book.PrintPreview(_variant_t(false));
	if (CoInitialize(NULL) == S_FALSE)
	{
		MessageBox(_T("初始化COM支持库失败!"));
		return;
	}

	if (!app.CreateDispatch(_T("Excel.Application"))); //创建IDispatch接口对象
	{
		//MessageBox(_T("Error!"));

	}


	books = app.get_Workbooks();
	book = books.Add(covOptional);


	sheets = book.get_Worksheets();
	sheet = sheets.get_Item(COleVariant((short)1));  //得到第一个工作表

	CHeaderCtrl   *pmyHeaderCtrl = l_list.GetHeaderCtrl(); //获取表头

	int   m_cols = pmyHeaderCtrl->GetItemCount(); //获取列数
	int   m_rows = l_list.GetItemCount();  //获取行数


	TCHAR     lpBuffer[256];

	HDITEM   hdi; //This structure contains information about an item in a header control. This structure has been updated to support header item images and order values.
	hdi.mask = HDI_TEXT;
	hdi.pszText = lpBuffer;
	hdi.cchTextMax = 256;

	CString   colname;
	CString strTemp;

	int   iRow, iCol;
	for (iCol = 0; iCol < m_cols; iCol++)//将列表的标题头写入EXCEL 
	{
		GetCellName(1, iCol + 1, colname); //(colname就是对应表格的A1,B1,C1,D1)

		range = sheet.get_Range(COleVariant(colname), COleVariant(colname));

		pmyHeaderCtrl->GetItem(iCol, &hdi); //获取表头每列的信息

		range.put_Value2(COleVariant(hdi.pszText));  //设置每列的内容

		int   nWidth = l_list.GetColumnWidth(iCol) / 6;

		//得到第iCol+1列   
		range.AttachDispatch(range.get_Item(_variant_t((long)(iCol + 1)), vtMissing).pdispVal, true);

		//设置列宽  
		range.put_ColumnWidth(_variant_t((long)nWidth));

	}

	range = sheet.get_Range(COleVariant(_T("A1 ")), COleVariant(colname));

	range.put_RowHeight(_variant_t((long)50));//设置行的高度 


	range.put_VerticalAlignment(COleVariant((short)-4108));//xlVAlignCenter   =   -4108 

	COleSafeArray   saRet; //COleSafeArray类是用于处理任意类型和维数的数组的类
	DWORD   numElements[] = { m_rows,m_cols };       //行列写入数组
	saRet.Create(VT_BSTR, 2, numElements); //创建所需的数组

	range = sheet.get_Range(COleVariant(_T("A2 ")), covOptional); //从A2开始
	range = range.get_Resize(COleVariant((short)m_rows), COleVariant((short)m_cols)); //表的区域

	long   index[2];

	for (iRow = 1; iRow <= m_rows; iRow++)//将列表内容写入EXCEL 
	{
		for (iCol = 1; iCol <= m_cols; iCol++)
		{
			index[0] = iRow - 1;
			index[1] = iCol - 1;

			CString   szTemp;

			szTemp = l_list.GetItemText(iRow - 1, iCol - 1); //取得l_list控件中的内容

			BSTR   bstr = szTemp.AllocSysString(); //The AllocSysString method allocates a new BSTR string that is Automation compatible

			saRet.PutElement(index, bstr); //把m_list控件中的内容放入saRet

			SysFreeString(bstr);
		}
	}



	range.put_Value2(COleVariant(saRet)); //将得到的数据的saRet数组值放入表格


	book.SaveCopyAs(COleVariant(cStrFile)); //保存到cStrFile文件
	book.put_Saved(true);



	books.Close();

	//

	book.ReleaseDispatch();
	books.ReleaseDispatch();

	app.ReleaseDispatch();
	app.Quit();

但是我用上面的代码运行后会报一堆错误,底层类好像有问题,所以改成了如下代码:

void CDlgStratueCal::OnBnClickedClistctrltoexc()
{
    CStringArray str11;
    for (int i = 0; i < l_list.GetItemCount(); i++)
	{
		str11.Add(l_list.GetItemText(i, 0));
		str11.Add(l_list.GetItemText(i, 1));
		str11.Add(l_list.GetItemText(i, 2));
	}
	CFileDialog fg(false, _T("*.csv"), NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
	_T("Excel CSV File(*.csv)|*.csv|Text File(*.txt)|*.txt|All File(*.*)|*.*||"), NULL);
	if (fg.DoModal() == IDOK)
	{
		CString filename = fg.GetPathName();
		CStdioFile file(filename, CFile::modeCreate | CFile::modeWrite);
		CString str = _T("序号,地层厚度,实际厚度\n");
		file.WriteString(str);
		for (int i = 0; i < str11.GetSize() - 1;)
		{
			if (i == 0)
			{
				str = str11.GetAt(i) + _T(",");
				str += str11.GetAt(++i) + _T(",");
				str += str11.GetAt(++i) + _T("\n");
			}
			else
			{
				str = str11.GetAt(++i) + _T(",");
				str += str11.GetAt(++i) + _T(",");
				str += str11.GetAt(++i) + _T("\n");
			}
			file.WriteString(str);
		}
		file.Close();
	}

}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值