excel变成xml格式_XML文件

excel变成xml格式_XML文件最近做了一个小工具,可以将XML和Excel之前互转。里面用到的XML读写库是tinyxml,在Excel2010上运行,请先确保装了Excel,而不是WPS。代码写的比较挫,一大坨,最近忙也懒得去做优化了。github地址:XML与Excel互转工具目前只支持ANSI格式的Excel文件与ANSI格式的XML文件互转。由于在写的时候,里面的存储方式都是CString,默认为ANS

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

最近做了一个小工具,可以将XML和Excel之前互转。

里面用到的XML读写库是tinyxml,在Excel2010上运行,请先确保装了Excel,而不是WPS。

代码写的比较挫,一大坨,最近忙也懒得去做优化了。

github地址:XML与Excel互转工具

目前只支持ANSI格式的Excel文件与ANSI格式的XML文件互转。由于在写的时候,里面的存储方式都是CString,默认为ANSI格式,所以哪怕里面把文字转成了UTF8,再保存到CString中也还是被认为是ANSI,这时候就会出现乱码,接下来如果有时间我会把这个问题修复。

直接讲讲代码吧。

读写xml,调用的是tinyxml的接口,核心部分代码都在这下面了,比较挫,分享给大家,希望有帮助。

/*分表和总表模式XML转Excel*/
void CReadXlsDlg::OnBnClickedButton3()
{
	// TODO:  在此添加控件通知处理程序代码
	// TODO:  在此添加控件通知处理程序代码
	CString strInputFile;
	CString strOutputPath;
	strInputFile.Empty();
	strOutputPath.Empty();
	m_editInputPath.GetWindowTextW(strInputFile);
	m_editOutputPath.GetWindowTextW(strOutputPath);

	//strInputFile = "C:\\Users\\linzhaolun.allen\\Desktop\\a.xml";
	//strOutputPath = "C:\\Users\\linzhaolun.allen\\Desktop\\b.xls";
	if (0 == strInputFile.GetLength())
	{
		MessageBox(_T("请先选择需要读取的文件"), _T("错误"), MB_OK);
		return;
	}
	if (0 == strOutputPath.GetLength())
	{
		MessageBox(_T("请先选择输出路径"), _T("错误"), MB_OK);
		return;
	}

	vector<vector<CString>> vecSheet;
	CSheetSize SheetSize;
	TiXmlDocument *doc = new TiXmlDocument(__CString2Constchar(strInputFile));
	if (!doc->LoadFile(TIXML_ENCODING_UTF8))  //判断XML文件是否加载成功
	{
		MessageBox(_T("无法打开该文件"), _T("错误"), MB_OK);
		return;
	}

	//doc->Parse(xmlParament,0,TIXML_ENCODING_UTF8);
    //目前仅支持合表模式xml的解析
	int BoHaveTitle = false;
	TiXmlElement* RootLayersNestedElement = doc->RootElement();
	if (NULL == RootLayersNestedElement) //判断文件是否有内容
	{
		MessageBox(_T("没有root element"), _T("错误"), MB_OK);
		return;
	}
	//cout << doc->Value() << endl;
	m_stroutputName = RootLayersNestedElement->Value();       //每个xml的root保存为文件名
	//cout << m_stroutputName << endl;
	m_mapSheetList.erase(m_mapSheetList.begin(), m_mapSheetList.end()); //注意使用map前对其进行清空
	m_mapSheetSize.erase(m_mapSheetSize.begin(), m_mapSheetSize.end());
	m_vecSheetName.clear();
	TiXmlElement* TwoLayersNestedElement = RootLayersNestedElement->FirstChildElement();   //第二层嵌套
	int nSheetCount =0;

	for (; TwoLayersNestedElement != NULL; TwoLayersNestedElement = TwoLayersNestedElement->NextSiblingElement()) 
	{  //每一层循环代表一个sheet

		CString strSheetName;
		CString strSpecialSheetPrefix("xxxxx");
		CString strList("List");
		//CString strConnectSheetAndAtti("yyyyy");
		vector<CString> sub_vecSheetName;  
		vector<CString>::iterator it;
		map<CString, CExcelSheet> sub_mapSheetList;
		strSheetName = TwoLayersNestedElement->Value();//获取sheet名
		//cout << strSheetName << endl;
		TiXmlElement* ThreeLayersNestedElement = TwoLayersNestedElement->FirstChildElement();  //第三层嵌套 
		if (TwoLayersNestedElement->FirstAttribute())
		{
			strSheetName = strSpecialSheetPrefix + strSheetName + strList;
			ThreeLayersNestedElement = TwoLayersNestedElement;
		}
		if (TwoLayersNestedElement->Value() != ThreeLayersNestedElement->Value())
		{
			//CString tempStr(ThreeLayersNestedElement->Value());
			//strSheetName = strSheetName + strConnectSheetAndAtti + tempStr;
			//MessageBox(_T("item和list之间命名规范错误!list名=item名+“list"), _T("错误"), MB_OK);
			//return;
		}
		for (; ThreeLayersNestedElement != NULL; ThreeLayersNestedElement = ThreeLayersNestedElement->NextSiblingElement())
		{	
			if (ThreeLayersNestedElement->FirstChildElement() && ThreeLayersNestedElement->FirstChildElement()->FirstChildElement())
			{
				TiXmlElement* FourLayersNestedElement = ThreeLayersNestedElement->FirstChildElement();  //第四层嵌套,相当于分表的Excel总表的展开,每一个为一个新的sheet,这个sheet的第一列,包含总是包含第三层的ID号作为索引
				  //第五层嵌套,新的sheet里面的每一项

				for (; FourLayersNestedElement != NULL; FourLayersNestedElement = FourLayersNestedElement->NextSiblingElement())//每一个循环意味着创建一个新的分表
				{
					CExcelSheet asheet;
					asheet.BoHaveTitle = false;
					asheet.strSheetName = FourLayersNestedElement->Value();//获取sheet名
					/*在vec中已经存在该sheet名,也就是之前已经有分表出现过了,此时要做的是把获得的数据push到之前的表内*/
					it = find(sub_vecSheetName.begin(), sub_vecSheetName.end(), asheet.strSheetName);
					if (it != sub_vecSheetName.end())
					{
						asheet = sub_mapSheetList[asheet.strSheetName];
					}
					vector<CString> vecSubRow, vecSubTitle;	
					vecSubTitle.push_back(__Constchar2CString(ConvertUtf8ToAnsi(ThreeLayersNestedElement->FirstAttribute()->Name())));
					vecSubRow.push_back(__Constchar2CString(ConvertUtf8ToAnsi(ThreeLayersNestedElement->FirstAttribute()->Value())));
					TiXmlElement* FiveLayersNestedElement = FourLayersNestedElement->FirstChildElement();
					for (; FiveLayersNestedElement != NULL; FiveLayersNestedElement = FiveLayersNestedElement->NextSiblingElement())
					{
						TiXmlAttribute* attributeOfFivelayers = FiveLayersNestedElement->FirstAttribute();  //获得属性 
						for (; attributeOfFivelayers != NULL; attributeOfFivelayers = attributeOfFivelayers->Next())
						{
							vecSubTitle.push_back(__Constchar2CString(ConvertUtf8ToAnsi(attributeOfFivelayers->Name())));
							vecSubRow.push_back(__Constchar2CString(ConvertUtf8ToAnsi(attributeOfFivelayers->Value())));
						}
						if (!asheet.BoHaveTitle){
							asheet.BoHaveTitle = true;
							asheet.vecSheet.push_back(vecSubTitle);
							vecSubTitle.clear();
							asheet.vecSheet.push_back(vecSubTitle);
							//SheetSize.row++;
						}
						asheet.vecSheet.push_back(vecSubRow);
						vecSubRow.clear();
						vecSubRow.push_back(__Constchar2CString(ConvertUtf8ToAnsi(ThreeLayersNestedElement->FirstAttribute()->Value())));
						it = find(sub_vecSheetName.begin(), sub_vecSheetName.end(), asheet.strSheetName);
						if (it == sub_vecSheetName.end())
						{
							sub_vecSheetName.push_back(asheet.strSheetName);
						}
						sub_mapSheetList[asheet.strSheetName] = asheet;			
					}						
				}
			}

			TiXmlAttribute* attributeOfThreelayers = ThreeLayersNestedElement->FirstAttribute();  //获得属性  
		
			vector<CString> vecRow, vecTitle;
			//SheetSize.row = SheetSize.col = 0;

			for (; attributeOfThreelayers != NULL; attributeOfThreelayers = attributeOfThreelayers->Next())
			{
				//cout << attributeOfThreelayers->Name() << ":" << attributeOfThreelayers->Value() << endl;

				vecTitle.push_back(__Constchar2CString(ConvertUtf8ToAnsi(attributeOfThreelayers->Name())));
				vecRow.push_back(__Constchar2CString(ConvertUtf8ToAnsi(attributeOfThreelayers->Value())));
				//SheetSize.col++;
			}
			if (!BoHaveTitle){
				BoHaveTitle = true;
				vecSheet.push_back(vecTitle);
				vecTitle.clear();
				vecSheet.push_back(vecTitle);
				//SheetSize.row++;
			}
			vecSheet.push_back(vecRow);
			//SheetSize.row++;
			
		}
		BoHaveTitle = false;
		m_mapSheetList[strSheetName] = vecSheet;
		//m_mapSheetSize[strSheetName] = SheetSize;
		m_vecSheetName.push_back(strSheetName);
		for (int i = 0; i < sub_vecSheetName.size(); i++)
		{
			m_vecSheetName.push_back(sub_vecSheetName[i]);
			m_mapSheetList[sub_vecSheetName[i]] = sub_mapSheetList[sub_vecSheetName[i]].vecSheet;
		}

		nSheetCount++;
		vecSheet.clear();
		sub_mapSheetList.erase(sub_mapSheetList.begin(), sub_mapSheetList.end()); //注意使用map前对其进行清空
		sub_vecSheetName.clear();
		
	}
    
	//将m_mapSheetList内容写入xls文件
	LPDISPATCH lpDisp = NULL;
	if (!m_obExcel.open(__CString2Constchar(strOutputPath)))
	{
		MessageBox(_T("无法打开该文件"), _T("错误"), MB_OK);
		return;
	}

	for (int i = m_vecSheetName.size()-1; i >=0 ; i--)
	{
		
		CString strSheetName = m_vecSheetName[i];
		if (!m_obExcel.addNewSheet(strSheetName))
		{
			MessageBox(_T("无法新建sheet"), _T("错误"), MB_OK);
			return;
		}
		try{
			m_obExcel.useSheet(strSheetName);
		}
		catch(...)
		{
			MessageBox(_T("无法使用指定sheet:")+strSheetName, _T("错误"), MB_OK);
			return;
		}
		
		vector<vector<CString>> vecTempSheet;
		vecTempSheet = m_mapSheetList[strSheetName];


		for(int tempRow=0; tempRow < vecTempSheet.size(); tempRow++)
		{

			vector<CString> vecTempRow;
			vecTempRow = vecTempSheet[tempRow];
			for(int tempCol=0; tempCol < vecTempRow.size(); tempCol++)
			{
				CString tempCell;
				tempCell = vecTempRow[tempCol];
				try{
					m_obExcel.setCellString(tempRow + 1, tempCol + 1, tempCell);
				}
				catch(...)
				{
					MessageBox(_T("无法使用写入cell,可能是坐标错误"), _T("错误"), MB_OK);
					return;
				}
			}
		}
	}
	m_obExcel.deleteSheet(__Constchar2CString("Sheet1"));
	m_obExcel.deleteSheet(__Constchar2CString("Sheet2"));
	m_obExcel.deleteSheet(__Constchar2CString("Sheet3"));
	m_obExcel.saveAsXLSFile(strOutputPath);  //此时生成的xls内为Ansi格式字符,xls再次转回XML时会被转码成为UTF-8
    m_obExcel.close();


	
}


版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/171944.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • SpringCloud之SpringCloud常见面试题, SOA和微服务关系, SpringCloud和Dubbo区别, Eureka和Zookeeper区别「建议收藏」

    SpringCloud之SpringCloud常见面试题, SOA和微服务关系, SpringCloud和Dubbo区别, Eureka和Zookeeper区别「建议收藏」1.SpringCloud是什么SpringCloud是一系列框架的集合,集成SpringBoot,提供很多优秀服务:服务发现和注册,统一配置中心,负载均衡,网关,熔断器等。2.SpringCloud的优势因为SpringCloud源于Spring,所以它的质量,稳定性,持续性都是可以保证的。SpringCloiud天热支持SpringBoot框架,就可以提高开发效率,能够实现需求。SpringCloud更新很快,后期支持很给力。SpringCloud可以用来开发微服务。3.Sp

    2022年6月4日
    35
  • convert dynamic命令在win10不可用_对目标文件系统,文件win7.gho过大

    convert dynamic命令在win10不可用_对目标文件系统,文件win7.gho过大全平台通过Termius,你可以安卓、Windows、macOS、Linux下来连接你的服务器,并且会在不同设备间同步,电脑做着做着要离开,换手机接着做官网链接:界面UI非常细腻win上面有xsheel,个人感觉xsheel更加强大。但是他不做Mac版本。由于在Mac上面用过Termius,所以习惯了他的界面。想要在win上面也用Termius汉化:手动方式打开当前这个js文件目录下面的这个js文件。然后全局搜索进行修改,但是一个一个改感觉麻烦创建一个termius.ini的文件,把下面这些复制进去

    2025年7月21日
    0
  • Ubuntu Edgy Eft complete sources.list (repository list file) (完整的ubuntu 源列表) Ubuntu Edgy Eft complete sources.list (repository

    Ubuntu Edgy Eft complete sources.list (repository list file) (完整的ubuntu 源列表) Ubuntu Edgy Eft complete sources.list (repository

    2021年4月28日
    113
  • 1/7的小数点后2020位的数字是_九八K

    1/7的小数点后2020位的数字是_九八K给定长度为 N 的整数序列 A,下标为 1∼N。现在要执行 M 次操作,其中第 i 次操作为给出三个整数 li,ri,ki,求 A[li],A[li+1],…,A[ri] (即 A 的下标区间 [li,ri])中第 ki 小的数是多少。输入格式第一行包含两个整数 N 和 M。第二行包含 N 个整数,表示整数序列 A。接下来 M 行,每行包含三个整数 li,ri,ki,用以描述第 i 次操作。输出格式对于每次操作输出一个结果,表示在该次操作中,第 k 小的数的数值。每个结果占一行。数据范围

    2022年8月9日
    3
  • python merge函数[通俗易懂]

    python merge函数[通俗易懂]本篇详细说明merge的应用,join和concatenate的拼接方法的与之相似。pd.merge(left,right,how=’inner’,on=None,left_on=None,right_on=None,left_index=False,right_index=False,sort=True,suffixes=(‘_x’,’_y’),copy=True,indicator=False,validate=No

    2022年5月2日
    74
  • idea 2022.01.4激活码(注册激活)2022.02.14

    (idea 2022.01.4激活码)最近有小伙伴私信我,问我这边有没有免费的intellijIdea的激活码,然后我将全栈君台教程分享给他了。激活成功之后他一直表示感谢,哈哈~https://javaforall.net/100143.htmlIntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,上面是详细链接哦~4KDD…

    2022年4月1日
    51

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号