用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. C#关于编码、解码相关问题

    编码.解码技术是我们在程序中开发中经常使用到的,对一些敏感信息的存储,比如密码之类的,我们一般是不会直接以明文直接存储到数据库的,而是会通过各种算法,可以是现成的MD5(一种散列算法).或者是Hash ...

  2. 前端资源多个产品整站一键打包&包版本管理(二)——如何在bower的配置文件加上注释

    问题: 当一个工程里面有好几个项目,每个项目引用同一个包,但是不同的名字,例如在bower中 fancybox 跟 jquery.fancybox 是一样的,我们只需要下载其中的一个版本,而打包工作不 ...

  3. MVC之重定向

    MVC的重定向主要通过RedirectResult和RedirectToRouteResult实现.很显然,这两个对象都是MVC返回对象ActionResult的两个继承,具体原理不赘述. 这两个方法 ...

  4. c# 判断窗体是否永在最前(TopMost),调用windows API

    许多程序都可以把自身的窗体设为最前显示状态,这个可以参考博客c#让窗体永在最前 调用windows api 将窗体设为topmost.那么如何判断桌面上的一个窗体是否为最前显示状态呢,不光是自己的程序 ...

  5. SIAlertView

    SIAlertView是AlertView的替代产品 的效果比较多 . 使用实例: SIAlertView *alertView = [[SIAlertView alloc] initWithTitl ...

  6. C++学习笔记37:元编程

    元编程 什么是元编程(metaprogramming) 利用模板可以进行编译期计算(数值计算,型式计算和代码计算)的特点进行程序设计 为什么可以进行元编程? C++是两层语言:执行编译期计算的代码称为 ...

  7. hdu 4286

    splay 练手用: 杭电的oj要手动开栈: #include<cstdio> #pragma comment(linker, "/STACK:102400000,1024000 ...

  8. unity 引入 ios 第三方sdk

    原地址:http://blog.csdn.net/u012085988/article/details/17785023 unity开发中ios应用时,要想成功引入第三方sdk,首先得知道c#与obj ...

  9. 【PHP框架CodeIgniter学习】使用辅助函数—建立自己的JSONHelper

    本文使用的是2.1.4版本,看的时候请注意. 官方文档:http://codeigniter.org.cn/user_guide/general/helpers.html(关于辅助函数Helper的使 ...

  10. *[codility]Number-of-disc-intersections

    http://codility.com/demo/take-sample-test/beta2010/ 这题以前做的时候是先排序再二分,现在觉得没有必要.首先圆可以看成线段,把线段的进入作为一个事件, ...