用Cocos开发模型特效工具编辑器,跨Mac和windows,当中有个需求是读取并解析excel文件,但网上的查找的例子几乎都只能是在windows下面使用,再或者是命令行脚本之类的。于是,自己写了一个非常轻量级的excel解析代码,纯cpp,除了依赖几个cocos2d 方法(zip解压和tinyxml2解析库),不依赖任何系统API。  目前只能解析常见的表式结构(如果把excel当成word文档使用就别看下面了),分享给大家,

如转发还请注明出处,感谢。

为了保证mac和windows都可以跑过,所以去掉注释,原谅我是VS菜鸟,当然代码够简单不写也能看懂。

getSheetArray返回的是excel的 行数组 ,因为c++里面难以实现动态类结构,所以不得已写成这种方式,一般情况下该数据拿到后需要二次加工,你可以拿一个简单的excel表格(比如道具物品表),测试打个断点就知道有哪些数据结构。 我还有一个纯js版本的,适合cocos2d-js使用,待日后完善了再丢出来。

//
// Excel.h
// 基于com.lipi.excel as3 版本设计,感谢lipi的源码参考
// Created by howe on 15/5/5.
// auto excel = new Excel();
// bool result = excel->parseExcelFile(filepath, 1);
// std::vector<LineInfo> arr = std::move( excel->getSheetArray() );
// #ifndef __ModelEditor__Excel__
#define __ModelEditor__Excel__ #include <stdio.h>
#include <vector>
#include <map> struct LineInfo
{
int lineIndex;
std::vector<std::string> array;
}; class Excel
{
public:
Excel(); bool parseExcelFile(const std::string &filepath,int sheetIndex); std::vector<LineInfo> getSheetArray(); private:
std::vector<std::string> _getValueArray();
private:
std::map<int,LineInfo> excelHash;
std::string _excelFilePath;
}; #endif /* defined(__ModelEditor__Excel__) */

Excel.cpp 实现部分

//
// Excel.cpp
//
// Created by howe on 15/5/5.
//
// #include <iostream>
#include <string> #include "Excel.h"
#include "cocos2d.h" #include "external/tinyxml2/tinyxml2.h" using namespace tinyxml2;
using namespace std; unsigned char* getFileDataFromZip(const std::string& zipFilePath, const std::string& filename, ssize_t *size)
{
return cocos2d::FileUtils::getInstance()->getFileDataFromZip(zipFilePath, filename, size);
} void deleteNum( std::string &content)
{
string::iterator t = content.begin();
while(t != content.end())
{
if(*t >= '0' && *t <= '9')
{
content.erase(t);
}
else
{
t++;
}
}
}
int getColIndex(std::string &content)
{
auto returnValue = 0;
for (auto i =0; i < content.length(); i++)
{
char n = content[i];
auto cValue = n - 64;
returnValue *= 26;
returnValue += cValue;
}
return returnValue - 1;
} Excel::Excel()
:_excelFilePath("")
{ } bool Excel::parseExcelFile(const std::string &ilepath, int sheetIndex)
{
_excelFilePath = ilepath;
excelHash.clear(); char xml_file[256] = {0};
sprintf(xml_file, "xl/worksheets/sheet%d.xml",sheetIndex+1);
ssize_t size; auto fileData = getFileDataFromZip(_excelFilePath, xml_file, &size);
if (!fileData)
{
CCLOG(ilepath.c_str(), "The excel file is not exist!");
return false;
}
auto valueArray = std::move(_getValueArray()); tinyxml2::XMLDocument doc; doc.Parse((const char*)fileData,size); XMLElement *root = doc.RootElement(); XMLElement * sheetDataElement = root->FirstChildElement("sheetData");
XMLElement * rowElement =sheetDataElement->FirstChildElement("row"); while (rowElement)
{
LineInfo lineInfo;
auto rowIndex = atoi(rowElement->Attribute("r")) - 1;
lineInfo.lineIndex = rowIndex;
std::vector<std::string> &rowArray = lineInfo.array;
auto cElement = rowElement->FirstChildElement("c");
while (cElement)
{
std::string cc = cElement->Attribute("r");
deleteNum(cc);
auto colIndex = getColIndex( cc );
std::string t = "";
std::string v = ""; if (cElement->Attribute("t"))
{
t = cElement->Attribute("t");
}
auto vElement = cElement->FirstChildElement("v");
if (vElement)
{
v = vElement->GetText();
}
if (rowArray.size() < colIndex)
{
int len = rowArray.size();
for (auto i = 0;i < colIndex - len;i++)
{
rowArray.push_back(""); //
}
}
if (t == "s")
{
rowArray.push_back(valueArray[atoi(v.c_str())]);
}
else
{
rowArray.push_back(v);
}
cElement = cElement->NextSiblingElement("c");
}
auto bb = false;
for (auto iii : rowArray)
{
if (iii.length() > 1)
{
bb = true;
break;
}
}
if (bb)
{
excelHash[rowIndex] = lineInfo;
}
rowElement = rowElement->NextSiblingElement("row");
}
return true;
} std::vector<std::string> Excel::_getValueArray()
{
std::vector<std::string> result; ssize_t size;
auto fileData = getFileDataFromZip(_excelFilePath, "xl/sharedStrings.xml", &size); tinyxml2::XMLDocument doc;
doc.Parse((const char*)fileData,size);
XMLElement *root = doc.RootElement();
XMLElement *siElement = root->FirstChildElement("si"); while (siElement)
{
std::string temp = "";
auto tElement = siElement->FirstChildElement("t");
while (tElement)
{
temp = temp + tElement->GetText();
tElement = tElement->NextSiblingElement("t");
}
result.push_back(temp);
siElement = siElement->NextSiblingElement("si");
}
return result;
} std::vector<LineInfo> Excel::getSheetArray()
{
std::vector<LineInfo> result;
for ( auto ite = excelHash.begin();ite != excelHash.end();ite++)
{
auto &lineInfo_ = ite->second;
result.push_back(lineInfo_);
}
return result;
}

c++ 读取并解析excel文件方法的更多相关文章

  1. Java通过jxl解析Excel文件入库,及日期格式处理方式 (附源代码)

    JAVA可以利用jxl简单快速的读取文件的内容,但是由于版本限制,只能读取97-03  xls格式的Excel. 本文是项目中用到的一个实例,先通过上传xls文件(包含日期),再通过jxl进行读取上传 ...

  2. 自动化测试如何解析excel文件?

    前言 自动化测试中我们存放数据无非是使用文件或者数据库,那么文件可以是csv,xlsx,xml,甚至是txt文件,通常excel文件往往是我们的首选,无论是编写测试用例还是存放测试数据,excel都是 ...

  3. Java:JXL解析Excel文件

    项目中,有需求要使用JXL解析Excel文件. 解析Excel文件 我们先要将文件转化为数据流inputStream. 当inputStream很大的时候 会造成Java虚拟器内存不够 抛出内存溢出 ...

  4. 解析Excel文件并把数据存入数据库

    前段时间做一个小项目,为了同时存储多条数据,其中有一个功能是解析Excel并把其中的数据存入对应数据库中.花了两天时间,不过一天多是因为用了"upload"关键字作为URL从而导致 ...

  5. Java中使用POI读取大的Excel文件或者输入流时发生out of memory异常参考解决方案

    注意:此参考解决方案只是针对xlsx格式的excel文件! 背景 前一段时间遇到一种情况,服务器经常宕机,而且没有规律性,查看GC日志发生了out of memory,是堆溢出导致的,分析了一下堆的d ...

  6. vue下载和上传excle数据文件,解析excel文件数据并存在数据库中

    下载: VUE: window.open("xxxx/downloadOldTaskDataFile.do_", "_blank"); JAVA: /** * ...

  7. C# 读取CSV和EXCEL文件示例

    我们习惯了直接连到数据库上面读取数据表的数据内容: 如果有一天我们需要读取CSV,EXCEL文件的内容的时候,可不可以也像读数据表的方式一样呢?当然可以,使用OleDB ADO.NET是很简单的事情 ...

  8. 【转】Python xlrd、xlwt、xlutils读取、修改Excel文件

    Python xlrd.xlwt.xlutils读取.修改Excel文件 一.xlrd读取excel 这里介绍一个不错的包xlrs,可以工作在任何平台.这也就意味着你可以在Linux下读取Excel文 ...

  9. Python解析excel文件并存入sqlite数据库

    最近由于工作上的需求 需要使用Python解析excel文件并存入sqlite 就此做个总结 功能:1.数据库设计 建立数据库2.Python解析excel文件3.Python读取文件名并解析4.将解 ...

随机推荐

  1. IT书籍下载汇总--持续更新

    本书单由北北分享,并持续更新,请将该地址加入收藏夹:北北的书单 .badge{float:right;}.list-group-item > .badge + .badge{margin-rig ...

  2. YII2框架动态创建表模型

    YII2框架动态创建表模型 在YII2中,每个表对应一个model类 在开发过程中,我们在填写一个大型表单的时候,表单里有N个select下拉列表,每个下拉select来自于不同的表: 如果要在程序里 ...

  3. 修改ECSHOP,支持图片云存储化(分离到专用图片服务器)

    为了提高页面加载速度和适应中国复杂的网络环境,我决定把所有商品图片都分离到专业的云存储服务器上,具有CDN加速功能. 首先,生成一个域名 img.xxxx.com 并映射到自己的云存储别名,然后把全部 ...

  4. ecshop二次开发 给商品添加自定义字段

    说起自定义字段,我想很多的朋友像我一样会想起一些开源的CMS(比如Dedecms.Phpcms.帝国)等,他们是可以在后台直接添加自定义字段的. 抱着这种想法我在Ecshop的后台一顿找,不过肿么都木 ...

  5. 特殊的Python

    在学习python之前,我也学习过C ,C++ ,Java ,PHP ,javascript,前端也学习过.但是在学习Python的这段时间里,多多少少也感觉到Python在语法方面的不同和特殊性. ...

  6. 关于vs2013 mysql Ef框架中提示版本不兼容问题的解决办法

    <runtime>     <assemblyBinding>       <dependentAssembly>         <assemblyIden ...

  7. 解决lucene 重复索引的问题

    在使用Lucene过程中,会发现当我们为添加新的Document时,会产生重复现象(两次添加同一个Document),毕竟Lucene中没有像数据库中一样,有键可以区分.不过我们可以通过为Docume ...

  8. winform 项目获取app.config 中appSettings节点数据

    <?xml version="1.0" encoding="utf-8" ?> <configuration> <configSe ...

  9. dos下的edit命令使用详解

    dos下的edit命令使用详解 来源:网络 作者:未知 edit命令是一个简单的编辑软件,我们经常用它来编辑一些程序和批处理文件. 比如,我想在c盘根目录下编辑一个简单的批处理文件,要求无论当前盘和当 ...

  10. Python属性、方法和类管理系列之----描述符类

    什么是描述符类? 根据鸭子模型理论,只要具有__get__方法的类就是描述符类. 如果一个类中具有__get__和__set__两个方法,那么就是数据描述符,. 如果一个类中只有__get__方法,那 ...