原创文章,欢迎转载,转载请注明:文章来自[寒江孤叶丶的Cocos2d-x之旅系列]
博客地址:http://blog.csdn.net/qq446569365
之前项目用CocoSutdio的数据编辑器导出的Json作为数据文件读取到游戏中,后来发现,效率太低的……低的可怜啊,于是开始选用Excel导出的CSV文件。从http://blog.csdn.net/znxf0702/article/details/42142045挖来了一段代码,但是存在一些不适用于被项目的问题。于是着手解决了两个主要问题1.CSV字符串换行的问题,2.第一个字段名有看不见的三个byte的问题。将代码分享出来,希望对大家有帮助
ChangeLog:
1.加入数字检测,现在能够转换为数字的都会以数字的形式存储
--[[
-------------------------------------------------
CsvLoader.lua
Created by ArcherPeng on 15-03-18.
-------------------------------------------------
功能概述:
本模块用于读取Excel导出的CSV文件,将读取的结果保存在一个table中
本模块支持换行功能,但需要特殊标记
在字符串开头加入#rrr表示开启换行,之后每加入一个#rrr则会换一次
例如:
#rrr普通副本#rrr挑战副本#rrr挂机副本#rrr日常副本#rrr
结果为
“
普通副本
挑战副本
挂机副本
日常副本
”
loadCsvFile(filePath,indexTitle)
filePath 文件的路径
indexTitle 作为teble的Key的字段
-------------------------------------------------
示例代码:
--test1
local testarr = loadCsvFile("data/test.csv")
for k,v in pairs(testarr[1]) do
print(k,v)
end
--test2
local testarr = loadCsvFile("data/test.csv","EquieID")
for k,v in pairs(testarr[1]) do
print(k,v)
end
--]]
_csv_log = function(...)
print(string.format(...))
end
function split(str, reps)
local resultStrsList = {};
string.gsub(str, '[^' .. reps ..']+', function(w) table.insert(resultStrsList, w) end );
return resultStrsList;
end
local function getRowContent(file)
local content;
local check = false
local count = 0
while true do
local t = file:read()
if not t then
if count == 0 then
check = true
end
break
end
if not content then
content = t
else
content = content..t
end
local i = 1
while true do
local index = string.find(t, "\"", i)
if not index then break end
i = index + 1
count = count + 1
end
if count % 2 == 0 then
check = true
break
end
end
if not check then
assert(1~=1)
end
return content and (string.trim(content))
end
--处理str是否需要换行,在字符串前加#rrr表示开启换行,然后所有需要换行的地方加入#rrr
local function dealStr(str)
if type(str) ~= "string" then
return str
end
local keyWord = string.sub(str,1,4)
if keyWord ~= "#rrr" then
return str
end
str = string.sub(str,5)
local strArr = string.split(str,"#rrr")
return table.concat(strArr,"\n")
end
function loadCsvFile(filePath,indexTitle)
if not filePath then return end
filePath = cc.FileUtils:getInstance():fullPathForFilename(filePath)
local alls = {}
local file = io.open(filePath, "r")
while true do
local line = getRowContent(file)
if not line then
break
end
table.insert(alls, line)
end
local titles = split(alls[1], ",")
for k,v in pairs(titles) do
if string.utf8len(titles[k]) ~= string.len(titles[k]) then
_csv_log("修正前:titles["..k.."] "..titles[k].." "..string.utf8len(titles[k]).." "..string.len(titles[k]))
titles[k] = string.sub(titles[k],string.len(titles[k]) - string.utf8len(titles[k]) + 2)
_csv_log("修正后:titles["..k.."] "..titles[k].." "..string.utf8len(titles[k]).." "..string.len(titles[k]))
end
end
local ID = 1
local arrs = {}
for i = 2, #alls, 1 do
local content = split(alls[i], ",")
local tabelArrs = {}
local index
local flg = false
for j = 1, #titles, 1 do
tabelArrs[titles[j]] = tonumber(content[j]) or dealStr(content[j])
-- print("titles[j] "..titles[j].." "..string.utf8len(titles[j]).." "..string.len(titles[j]))
if indexTitle and indexTitle == titles[j] then
index = tonumber(content[j]) or content[j]
flg = true
end
end
if flg then
arrs[index] = tabelArrs
else
arrs[ID] = tabelArrs
end
ID = ID + 1
end
return arrs
end
_G.APUtils = _G.APUtils or {}
_G.APUtils.LoadCsv = _G.APUtils.loadCsvFile or loadCsvFile