Excel動態生成JSON


在最近的一個項目中,有大量的數據源來至Excel,轉成JSON供前台使用。Excel數據是人工錄入的,難免會有錯誤,所以中間會有邏輯檢查。在C#中讀取Excel的方式有很多,網上一搜一大堆,這里我也貼出一個ExcelHelper,提供根據Excel文件獲取所有Sheet名稱和獲取Sheet內容兩個方法。使用的時候記得注冊AccessDatabaseEngine,該驅動有64位、32位兩個版本,請根據自己的環境選擇正確的版本。

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.Linq;

namespace Math.Library.Helper
{
    public class ExcelHelper
    {
        public static DataTable GetExcelContent(String filePath, string sheetName)
        {
            if (sheetName == "_xlnm#_FilterDatabase")
                return null;
            DataSet dateSet = new DataSet();
            String connectionString = String.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties='Excel 12.0;HDR=NO;IMEX=1;'", filePath);
            String commandString = string.Format("SELECT * FROM [{0}$]", sheetName);
            using (OleDbConnection connection = new OleDbConnection(connectionString))
            {
                connection.Open();
                using (OleDbCommand command = new OleDbCommand(commandString, connection))
                {
                    OleDbCommand objCmd = new OleDbCommand(commandString, connection);
                    OleDbDataAdapter myData = new OleDbDataAdapter(commandString, connection);
                    myData.Fill(dateSet, sheetName);
                    DataTable table = dateSet.Tables[sheetName];

                    for (int i = 0; i < table.Rows[0].ItemArray.Length; i++)
                    {
                        var cloumnName = table.Rows[0].ItemArray[i].ToString();
                        if (!string.IsNullOrEmpty(cloumnName))
                            table.Columns[i].ColumnName = cloumnName;
                    }
                    table.Rows.RemoveAt(0);
                    return table;
                }
            }
        }

        public static List<string> GetExcelSheetNames(string filePath)
        {
            OleDbConnection connection = null;
            System.Data.DataTable dt = null;
            try
            {
                String connectionString = String.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties='Excel 12.0;HDR=YES;IMEX=1;'", filePath);
                connection = new OleDbConnection(connectionString);
                connection.Open();
                dt = connection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);

                if (dt == null)
                {
                    return new List<string>();
                }

                String[] excelSheets = new String[dt.Rows.Count];
                int i = 0;
                foreach (DataRow row in dt.Rows)
                {
                    excelSheets[i] = row["TABLE_NAME"].ToString().Split('$')[0];
                    i++;
                }
                return excelSheets.Distinct().ToList();
            }
            catch (Exception ex)
            {
                LogHelper.Logger.Error(ex);
                return new List<string>();
            }
            finally
            {
                if (connection != null)
                {
                    connection.Close();
                    connection.Dispose();
                }
                if (dt != null)
                {
                    dt.Dispose();
                }
            }
        }

    }
}

假如我的Excel數據如下,有班級和學生兩張表(實際上有上百個Sheet,這里只做演示之用)。

image

image

當然我們不可能為每一個Sheet都對應做一個數據Model,不僅繁瑣,還很容易出錯。這時我想到了Newtonsoft.Json,Newtonsoft.Json是.NET下開源的JSON格式序列化和反序列化的類庫。其中Newtonsoft.Json.Linq提供了對LINQ支持,支持動態對象、數組的序列化。

將整個Excel轉換為一個JSON文件,每一個Sheet Name作為Key,Content就是Value,Value以數組形式存在,最終得到數據格式如下:

image

對應的代碼如下,JArray和JObject是Newtonsoft.Json中的對象,支持動態屬性和方法,表名和列名就是這樣插入JSON中的。

class Program
{
    static void ExcelToJson()
    {
        List<string> tableNames = ExcelHelper.GetExcelSheetNames("test.xlsx");
        var json = new JObject();
        tableNames.ForEach(tableName =>
        {
            var table = new JArray() as dynamic;
            DataTable dataTable = ExcelHelper.GetExcelContent("test.xlsx", tableName);
            foreach (DataRow dataRow in dataTable.Rows)
            {
                dynamic row = new JObject();
                foreach (DataColumn column in dataTable.Columns)
                {
                    row.Add(column.ColumnName, dataRow[column.ColumnName].ToString());
                }
                table.Add(row);
            }
            json.Add(tableName, table);
        });
        Console.WriteLine(json.ToString());
        Console.WriteLine(json.ToString(Formatting.None));
    }

    static void Main(string[] args)
    {
        ExcelToJson();
    }
}

當然,為了減少前后端傳輸數據的流量,可以使用ToString(Formatting.None),這樣生成出來的數據就沒有格式了。

image


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM