原创文章,欢迎转载,转载请注明:文章来自[寒江孤叶丶的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) 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