-
Notifications
You must be signed in to change notification settings - Fork 493
/
Copy pathJsonExporter.cs
224 lines (194 loc) · 8.38 KB
/
JsonExporter.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
using System;
using System.IO;
using System.Data;
using System.Text;
using System.Collections.Generic;
using Newtonsoft.Json;
namespace excel2json
{
/// <summary>
/// 将DataTable对象,转换成JSON string,并保存到文件中
/// </summary>
class JsonExporter
{
string mContext = "";
int mHeaderRows = 0;
public string context {
get {
return mContext;
}
}
/// <summary>
/// 构造函数:完成内部数据创建
/// </summary>
/// <param name="excel">ExcelLoader Object</param>
public JsonExporter(ExcelLoader excel, bool lowcase, bool exportArray, string dateFormat, bool forceSheetName, int headerRows, string excludePrefix, bool cellJson, bool allString)
{
mHeaderRows = headerRows - 1;
List<DataTable> validSheets = new List<DataTable>();
for (int i = 0; i < excel.Sheets.Count; i++)
{
DataTable sheet = excel.Sheets[i];
// 过滤掉包含特定前缀的表单
string sheetName = sheet.TableName;
if (excludePrefix.Length > 0 && sheetName.StartsWith(excludePrefix))
continue;
if (sheet.Columns.Count > 0 && sheet.Rows.Count > 0)
validSheets.Add(sheet);
}
var jsonSettings = new JsonSerializerSettings
{
DateFormatString = dateFormat,
Formatting = Formatting.Indented
};
if (!forceSheetName && validSheets.Count == 1)
{ // single sheet
//-- convert to object
object sheetValue = convertSheet(validSheets[0], exportArray, lowcase, excludePrefix, cellJson, allString);
//-- convert to json string
mContext = JsonConvert.SerializeObject(sheetValue, jsonSettings);
}
else
{ // mutiple sheet
Dictionary<string, object> data = new Dictionary<string, object>();
foreach (var sheet in validSheets)
{
object sheetValue = convertSheet(sheet, exportArray, lowcase, excludePrefix, cellJson, allString);
data.Add(sheet.TableName, sheetValue);
}
//-- convert to json string
mContext = JsonConvert.SerializeObject(data, jsonSettings);
}
}
private object convertSheet(DataTable sheet, bool exportArray, bool lowcase, string excludePrefix, bool cellJson, bool allString)
{
if (exportArray)
return convertSheetToArray(sheet, lowcase, excludePrefix, cellJson, allString);
else
return convertSheetToDict(sheet, lowcase, excludePrefix, cellJson, allString);
}
private object convertSheetToArray(DataTable sheet, bool lowcase, string excludePrefix, bool cellJson, bool allString)
{
List<object> values = new List<object>();
int firstDataRow = mHeaderRows;
for (int i = firstDataRow; i < sheet.Rows.Count; i++)
{
DataRow row = sheet.Rows[i];
values.Add(
convertRowToDict(sheet, row, lowcase, firstDataRow, excludePrefix, cellJson, allString)
);
}
return values;
}
/// <summary>
/// 以第一列为ID,转换成ID->Object的字典对象
/// </summary>
private object convertSheetToDict(DataTable sheet, bool lowcase, string excludePrefix, bool cellJson, bool allString)
{
Dictionary<string, object> importData =
new Dictionary<string, object>();
int firstDataRow = mHeaderRows;
for (int i = firstDataRow; i < sheet.Rows.Count; i++)
{
DataRow row = sheet.Rows[i];
string ID = row[sheet.Columns[0]].ToString();
if (ID.Length <= 0)
ID = string.Format("row_{0}", i);
var rowObject = convertRowToDict(sheet, row, lowcase, firstDataRow, excludePrefix, cellJson, allString);
// 多余的字段
// rowObject[ID] = ID;
importData[ID] = rowObject;
}
return importData;
}
/// <summary>
/// 把一行数据转换成一个对象,每一列是一个属性
/// </summary>
private Dictionary<string, object> convertRowToDict(DataTable sheet, DataRow row, bool lowcase, int firstDataRow, string excludePrefix, bool cellJson, bool allString)
{
var rowData = new Dictionary<string, object>();
int col = 0;
foreach (DataColumn column in sheet.Columns)
{
// 过滤掉包含指定前缀的列
string columnName = column.ToString();
if (excludePrefix.Length > 0 && columnName.StartsWith(excludePrefix))
continue;
object value = row[column];
// 尝试将单元格字符串转换成 Json Array 或者 Json Object
if (cellJson)
{
string cellText = value.ToString().Trim();
if (cellText.StartsWith("[") || cellText.StartsWith("{"))
{
try
{
object cellJsonObj = JsonConvert.DeserializeObject(cellText);
if (cellJsonObj != null)
value = cellJsonObj;
}
catch (Exception exp)
{
}
}
}
if (value.GetType() == typeof(System.DBNull))
{
value = getColumnDefault(sheet, column, firstDataRow);
}
else if (value.GetType() == typeof(double))
{ // 去掉数值字段的“.0”
double num = (double)value;
if ((int)num == num)
value = (int)num;
}
//全部转换为string
//方便LitJson.JsonMapper.ToObject<List<Dictionary<string, string>>>(textAsset.text)等使用方式 之后根据自己的需求进行解析
if (allString && !(value is string))
{
value = value.ToString();
}
string fieldName = column.ToString();
// 表头自动转换成小写
if (lowcase)
fieldName = fieldName.ToLower();
if (string.IsNullOrEmpty(fieldName))
fieldName = string.Format("col_{0}", col);
rowData[fieldName] = value;
col++;
}
return rowData;
}
/// <summary>
/// 对于表格中的空值,找到一列中的非空值,并构造一个同类型的默认值
/// </summary>
private object getColumnDefault(DataTable sheet, DataColumn column, int firstDataRow)
{
for (int i = firstDataRow; i < sheet.Rows.Count; i++)
{
object value = sheet.Rows[i][column];
Type valueType = value.GetType();
if (valueType != typeof(System.DBNull))
{
if (valueType.IsValueType)
return Activator.CreateInstance(valueType);
break;
}
}
return "";
}
/// <summary>
/// 将内部数据转换成Json文本,并保存至文件
/// </summary>
/// <param name="jsonPath">输出文件路径</param>
public void SaveToFile(string filePath, Encoding encoding)
{
//-- 保存文件
using (FileStream file = new FileStream(filePath, FileMode.Create, FileAccess.Write))
{
using (TextWriter writer = new StreamWriter(file, encoding))
writer.Write(mContext);
}
}
}
}