最近做了一个小工具,可以将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()) {  //每一层循环代表一个sheetCString 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-8m_obExcel.close();}


												

XML转Excel或Excel转XML|tinyxml简单使用|C++使用excel相关推荐

  1. 一文搞定Qt读写excel以及qt读写xml数据

    一文搞定Qt读写excel以及qt读写xml数据 最终的实现效果图 RC_ICONS = logo.ico .pro文件同级目录下加入 logo.ico 图标文件,运行文件,文件的图标就被写入软件 u ...

  2. Unity 基础 之 xml 使用 Office Excel 轻松编辑保存 xml 数据,并解析读取数据

    Unity 基础 之 xml  使用 Office Excel 轻松编辑保存 xml 数据 目录 Unity 基础 之 xml  使用 Office Excel 轻松编辑保存 xml 数据 一.简单介 ...

  3. TestLink在线Excel用例转换xml

    [原文链接]:https://blog.tecchen.xyz ,博文同步发布到博客园. 由于精力有限,对文章的更新可能不能及时同步,请点击上面的原文链接访问最新内容. 欢迎访问我的个人网站:http ...

  4. 将excel表格数据转换为xml文本数据

    原文:http://blog.javayc.com/archives/12 这篇blog主要是讲述java中poi读取excel,并将excel中的数据转化为xml文本中的数据,而excel的版本包括 ...

  5. EXCEL表格转化为XML格式文件

    EXCEL表格转化为XML格式文件 这里给出一个例子: 将get_1.csv文件转化为xml格式文件. 同时将里面的正文部分用jieba进行切词,使得正文每一个词都带有id和词性: from xml. ...

  6. Java实现从Excel文件转换成XML文件(一)

    实现思路:         直接从Excel文件装换成XML文件是可以实现的,这里我采用一个中间装换,也就是先实现excel文件内容放入实现设计好的access数据库文件中,然后再从access中读取 ...

  7. Excel 数据导入SQL XML 自动生成表头

    去出差的时候应客户要求要要将Excel 文件内的数据批量导入到数据库中,而且有各种不同种类的表格,如果每一个表格多对应一个数据表的话, 按照正常的方法应该是创建数据表,创建数据库中映射的数据模型,然后 ...

  8. Java实现Excel和Office Open XML之间的相互转换

    前言 Office Open XML(也被称为OOXML)是一种压缩的.基于XML的Excel.Word和演示文档格式.有时,你可能需要将Excel文件转换为Office Open XML,以使其在各 ...

  9. java实现excel文件上传_java相关:SpringMVC下实现Excel文件上传下载

    java相关:SpringMVC下实现Excel文件上传下载 发布于 2020-6-21| 复制链接 摘记: 在实际应用中,经常会遇到上传Excel或者下载Excel的情况,比如导入数据.下载统计数据 ...

最新文章

  1. CF231C To Add or Not to Add(思维,模拟)
  2. 算法工程师的必备学习资料,《AI算法工程师手册》正式开源了
  3. EIGRP-2(EIGRP的路由认证)
  4. Hadoop详解(九):Hadoop Streaming和Pipes原理和实现
  5. 解析:Python适合哪些人学呢?
  6. 【redis】使用 URI 配置 redis
  7. webspere php,Project Zero、WebSphere sMash、PHP和JAVA的整合
  8. excel合并计算_【Excel】合并计算和模拟分析的应用
  9. 软件工程 --第七章 -- 实现(未完)
  10. raspberry pi_在Raspberry Pi上使用Mathematica进行高级数学运算
  11. 北京文化:目前《你好李焕英》贡献营收约6000万至6500万元
  12. C语言函数指针简单应用
  13. android系统关闭wifi,Android以编程方式打开/关闭WiFi HotSpot
  14. 使用scroll实现Elasticsearch数据遍历和深度分页
  15. 对 粒子滤波算法原理 的介绍,通俗易懂
  16. 如何在Word中绘制流程图
  17. android lrc歌词解析,Android解析lrc里的歌词
  18. 《深度学习:走向核心素养》学习体会
  19. sequence生成器写法
  20. 微课竞赛系统的设计与实现所需工作条件_启升微课丨如何准备医疗器械软件开发计划...

热门文章

  1. Oracle和Java数据类型对应关系
  2. 西南交通大学计算机历年复试线,2020西南交通大学考研复试分数线已公布
  3. 特斯拉E/E整车电子电气创新架构分析
  4. 【工作精华】【金融知识】总账轧差科目
  5. 双管齐下,华为云DWS智能云数仓+商业智能联合
  6. 联通突然从4g变成3g了_联通4G跳到3G无法上网,如何恢复4G上网?
  7. Linux screen简单用法
  8. 05. 聚类---K(k-means)均值
  9. 如何解决 通用 ERROR: This script does not work on Python 2.7 The minimum supported Python version is 3.7
  10. 手记_Apache Tiles