做U3d编辑器xlsx批量生成csv
xlsx编辑就是用强大的office Excel 2013 ,
也就是说 不管是程序还是美术只需要维护这个Excel就够了,然后一键批量转化为csv文件即可! 打包不会打包Excel,游戏中也不用这个!然后来到Unity3d的编辑器菜单。
在Unity的Editor文件夹下面需要这四个文件:
参考了:http://www.codeproject.com/Articles/246772/Convert-xlsx-xls-to-csv 的window窗口程序。
游戏中使用CSV的方法,在github上有一个很好的方法:https://github.com/cunkai/Unity-CSV-To-C-Sharp
Unity CSV转为C#文件 来省去解析csv的步骤,节省游戏加载时间。
有人会问?为什么不直接使用Excel的xlsx文件,因为相同的内容文件大小比csv大很多。
看看代码吧: 相关的路径可以根据项目进行更改!
using UnityEngine;
using System.Data;
using System.IO;
using Excel;
using UnityEditor;
/// <summary>
/// Xlsl to CS.
/// </summary>
public class XlslToCSV : EditorWindow {
static string foldername = Application.dataPath;
static DataSet result = new DataSet();
[MenuItem("Games/Excel To CSV &%#c")]
// 要访问的Excel
static void Menu_Click()
{
string Chosen_File = Application.dataPath + "/Editor" + "/test.xlsx"; // Excel的 xlsx的文件路径
getExcelData(Chosen_File);
}
static void getExcelData(string file)
{
if (file.EndsWith(".xlsx"))
{
// Reading from a binary Excel file (format; *.xlsx)
FileStream stream = File.Open(file, FileMode.Open, FileAccess.Read);
IExcelDataReader excelReader = ExcelReaderFactory.CreateOpenXmlReader(stream);
result = excelReader.AsDataSet();
excelReader.Close();
}
if (file.EndsWith(".xls"))
{
// Reading from a binary Excel file ('97-2003 format; *.xls)
FileStream stream = File.Open(file, FileMode.Open, FileAccess.Read);
IExcelDataReader excelReader = ExcelReaderFactory.CreateBinaryReader(stream);
result = excelReader.AsDataSet();
excelReader.Close();
}
// List<string> items = new List<string>(); // 得到所有表的表名
for (int i = 0; i < result.Tables.Count; i++) {
// items.Add(result.Tables[i].TableName.ToString());
converToCSV(i, result.Tables[i].TableName.ToString());
}
}
static void converToCSV(int index, string OLdfileName)
{
// sheets in excel file becomes tables in dataset
//result.Tables[0].TableName.ToString(); // to get sheet name (table name)
string a = "";
int row_no = 0;
while (row_no < result.Tables[index].Rows.Count)
{
for (int i = 0; i < result.Tables[index].Columns.Count; i++)
{
a += result.Tables[index].Rows[row_no][i].ToString() + ",";
}
row_no++;
a += "\n";
}
string output = foldername + "/Editor" + "\\" + OLdfileName + ".csv"; // 要保存的文件路径
StreamWriter csv = new StreamWriter(@output, false);
csv.Write(a);
csv.Close();
Debug.Log("File converted succussfully");
return;
}
}
其实这样做也是存在一个问题,策划也是很少使用Unity的, 他们在配置完xlsx后总不能都要打开Unity然后点击菜单进行转化吧。
那么现在就说说强大的python实现方式: 参考https://github.com/amengren/xls2csv
也是借助第三方的扩展。
将xls xlsx 格式的文件转换为csv(','分隔,以‘\\n’行结束符(当然也可以设置为其他的呀!))
需要安装xlrd模块 https://pypi.python.org/pypi/xlrd (安装说明在本文最后!)
使用方法:
将xls文件和当前模块放同一个文件夹,执行脚本,自动在当前文件生成csv
xls2csv.py
# encoding: utf-8
import os,sys,inspect,re
import xdrlib,xlrd
reload(sys)
sys.setdefaultencoding("utf-8")
#分割符
C_SPACE = ","
#结束符
C_END = "\n"
#获取脚本文件的当前路径
def cur_file_dir():
path = os.path.realpath(sys.path[0])
print path
if os.path.isfile(path):
print "exe"
path = os.path.dirname(path)
return os.path.abspath(path)
else:
print "文件"
caller_file = inspect.stack()[1][1]
return os.path.abspath(os.path.dirname(caller_file))
#搜索指定文件夹下面的文件(默认当前目录)
def find_file_by_pattern(pattern='.*', base=".", circle=True):
'''''查找给定文件夹下面所有 '''
re_file = re.compile(pattern)
if base == ".":
base = cur_file_dir()
print "开始搜索文件夹:",base
final_file_list = []
cur_list = os.listdir(base)
for item in cur_list:
# print item
if item == ".svn":
continue
full_path = os.path.join(base, item)
if full_path.startswith("~"):
continue
if full_path.endswith(".xlsx") or full_path.endswith(".xls"):
print "in:" + full_path
bfile = os.path.isfile(item)
if os.path.isfile(full_path):
if re_file.search(full_path):
final_file_list.append(full_path)
else:
final_file_list += find_file_by_pattern(pattern, full_path)
'''返回文件列表'''
return final_file_list
#打开excel
def open_excel(file= 'file.xls'):
try:
data = xlrd.open_workbook(file)
return data
except Exception,e:
print str(e)
#根据索引获取Excel表格中的数据 参数:file:Excel文件路径, colnameindex:表头列名所在行的索引, by_index:表的索引
def excel_table_byindex(file='file.xls', colnameindex=0, by_index=0):
data = open_excel(file)
table = data.sheets()[by_index]
nrows = table.nrows #行数
ncols = table.ncols #列数
rowlist = []
# print heads
'''开始读取数据'''
for rownum in range(colnameindex, nrows):
rowdata = table.row_values(rownum)
if rowdata:
collist = []
for i in range(ncols):
collist.append(rowdata[i])
rowlist.append(collist)
return rowlist
#保存csv文件
def savaToCSV(_file, _list, _path):
filename = ""
content = ""
#生成文件内容
for collist in _list:
for i in range(len(collist)):
v = collist[i]
vstr = ""
# print k,v
if isinstance(v, float) or isinstance(v, int):
vstr = str(int(v))
else:# elif isinstance(v, str):
vstr = v
if i > 0:
content = content + C_SPACE
content = content + vstr
content = content + C_END
#生成文件后缀
fname = os.path.splitext(_file)
filename = fname[0] + ".csv"
#写文件
if len(filename)>0 and len(content)>0:
# filename = _path + "/" + filename
print "out:" + filename
file_object = open(filename, 'w')
file_object.write(content)
file_object.close()
def main():
filelist = find_file_by_pattern()
if len(filelist) > 0:
path = ""
# if not os.path.isdir(path):
# os.makedirs(path)
#遍历文件生成csv
for file in filelist:
datalist = excel_table_byindex(file, 0)
if len(datalist)>0:
savaToCSV(file, datalist, path)
else:
print "没有找到任何excel技能文件!"
if __name__=="__main__":
main()
ps:记住,路径直接用分号“;”隔开!