using System; using System.IO; using System.Data; using System.Text; using System.Collections.Generic; using Newtonsoft.Json; namespace excel2json { /// /// 将DataTable对象,转换成JSON string,并保存到文件中 /// class JsonExporter { string mContext = ""; int mHeaderRows = 0; public string context { get { return mContext; } } /// /// 构造函数:完成内部数据创建 /// /// ExcelLoader Object public JsonExporter(ExcelLoader excel, bool lowcase, bool exportArray, string dateFormat, bool forceSheetName, int headerRows, string excludePrefix, bool cellJson) { mHeaderRows = headerRows - 1; List validSheets = new List(); 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); //-- convert to json string mContext = JsonConvert.SerializeObject(sheetValue, jsonSettings); } else { // mutiple sheet Dictionary data = new Dictionary(); foreach (var sheet in validSheets) { object sheetValue = convertSheet(sheet, exportArray, lowcase, excludePrefix, cellJson); 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) { if (exportArray) return convertSheetToArray(sheet, lowcase, excludePrefix, cellJson); else return convertSheetToDict(sheet, lowcase, excludePrefix, cellJson); } private object convertSheetToArray(DataTable sheet, bool lowcase, string excludePrefix, bool cellJson) { List values = new List(); int firstDataRow = mHeaderRows; for (int i = firstDataRow; i < sheet.Rows.Count; i++) { DataRow row = sheet.Rows[i]; var rowObject = convertRowToDict(sheet, row, lowcase, firstDataRow, excludePrefix, cellJson); if (rowObject != null) values.Add(rowObject); } return values; } /// /// 以第一列为ID,转换成ID->Object的字典对象 /// private object convertSheetToDict(DataTable sheet, bool lowcase, string excludePrefix, bool cellJson) { Dictionary importData = new Dictionary(); 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); // 多余的字段 // rowObject[ID] = ID; if (rowObject != null) importData[ID] = rowObject; } return importData; } /// /// 把一行数据转换成一个对象,每一列是一个属性 /// private Dictionary convertRowToDict(DataTable sheet, DataRow row, bool lowcase, int firstDataRow, string excludePrefix, bool cellJson) { string keyColumn = row[sheet.Columns[0]].ToString(); if (excludePrefix.Length > 0 && keyColumn.StartsWith(excludePrefix)) return null; var rowData = new Dictionary(); 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 fieldName = column.ToString(); // 表头自动转换成小写 if (lowcase) fieldName = fieldName.ToLower(); if (string.IsNullOrEmpty(fieldName)) fieldName = string.Format("col_{0}", col); rowData[fieldName] = value; col++; } return rowData; } /// /// 对于表格中的空值,找到一列中的非空值,并构造一个同类型的默认值 /// 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 ""; } /// /// 将内部数据转换成Json文本,并保存至文件 /// /// 输出文件路径 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); } } } }