JsonExporter.cs 7.9 KB

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