.NET JSON / Excel 轉換範例
2 |
被問到有沒有 JSON 轉 Excel 的 .NET 範例,雖然是柴米油鹽級的簡單任務,一查還真沒寫過,念在這也算常遇到的應用場景,順手補上唄~
假設有 JSON 如下:
[
{
"Name": "John Doe",
"Age": 28,
"Country": "USA",
"Email": "johndoe@example.com",
"RegDate": "2023-10-04T08:23:55Z"
},
{
"Name": "Jane Smith",
"Age": 35,
"Country": "UK",
"Email": "janesmith@example.com",
"RegDate": "2023-10-04T11:46:30Z"
},
{
"Name": "Alice Jones",
"Age": 29,
"Country": "Australia",
"Email": "alicej@example.com",
"RegDate": "2023-10-04T15:02:43Z"
},
{
"Name": "Bob Brown",
"Age": 46,
"Country": "Canada",
"Email": "bobbrown@example.com",
"RegDate": "2023-10-04T22:19:17Z"
},
{
"Name": "Eve White",
"Age": 32,
"Country": "Germany",
"Email": "evew@example.com",
"RegDate": "2023-10-04T03:58:29Z"
},
{
"Name": "Charlie Black",
"Age": 22,
"Country": "Japan",
"Email": "charlieb@example.com",
"RegDate": "2023-10-04T17:34:08Z"
}
]
轉 Excel 的重責大任當然是交給 ClosedXML 了。先示範 .NET Framework + Json.NET 版本:
using ClosedXML.Excel;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.IO;
using System.Linq;
namespace NetFxDemo
{
internal class Program
{
static void Main(string[] args)
{
var json = File.ReadAllText("sample.json");
var data = JsonConvert.DeserializeObject<JObject[]>(json);
var wb = new XLWorkbook();
var ws = wb.Worksheets.Add("sample");
var headers = data.First().Properties().Select(p => p.Name).ToList();
for (int i = 0; i < headers.Count; i++)
{
ws.Cell(1, i + 1).Value = headers[i];
}
var headerRow = ws.Row(1);
headerRow.Style.Font.Bold = true;
headerRow.Style.Fill.BackgroundColor = XLColor.LightGray;
headerRow.Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center;
for (int i = 0; i < data.Length; i++)
{
var properties = data[i].Properties();
int j = 1;
foreach (var property in properties)
{
var valueType = property.Value.Type;
var value = property.Value;
switch (valueType)
{
case JTokenType.Integer:
case JTokenType.Float:
ws.Cell(i + 2, j++).Value = value.ToObject<double>();
break;
case JTokenType.Date:
ws.Cell(i + 2, j++).Value = value.ToObject<DateTime>().ToString("yyyy-MM-dd HH:mm:ss");
break;
default:
ws.Cell(i + 2, j++).Value = value.ToString();
break;
}
}
}
ws.Columns().AdjustToContents();
ws.Columns().ToList().ForEach(c => c.Width = c.Width + 1);
wb.SaveAs("output.xlsx");
}
}
}
針對數字及日期型別我加了一些額外邏輯,比起一律轉字串,Excel 顯示樣式會更精緻一些,這部分可依實際需求調整以符合期望結果。
再示範 .NET 6+ 搭配 System.Text.Json 如何完成。
using ClosedXML.Excel;
using System.Text.Json;
var json = File.ReadAllText("sample.json");
var data = JsonSerializer.Deserialize<JsonElement[]>(json);
var wb = new XLWorkbook();
var ws = wb.Worksheets.Add("sample");
var headers = data.First().EnumerateObject().Select(p => p.Name).ToList();
for (int i = 0; i < headers.Count; i++)
{
ws.Cell(1, i + 1).Value = headers[i];
}
var headerRow = ws.Row(1);
headerRow.Style.Font.Bold = true;
headerRow.Style.Fill.BackgroundColor = XLColor.LightGray;
headerRow.Style.Alignment.Horizontal = XLAlignmentHorizontalValues.Center;
for (int i = 0; i < data.Length; i++)
{
var properties = data[i].EnumerateObject();
int j = 1;
foreach (var property in properties)
{
var valueKind = property.Value.ValueKind;
if (valueKind == JsonValueKind.Number)
{
ws.Cell(i + 2, j++).Value = property.Value.GetDouble();
}
else
{
string valueString = property.Value.ToString();
if (valueKind == JsonValueKind.String &&
DateTime.TryParse(valueString, out DateTime date))
valueString = date.ToString("yyyy-MM-dd HH:mm:ss");
ws.Cell(i + 2, j++).Value = valueString;
}
}
}
ws.Columns().AdjustToContents();
ws.Columns().ToList().ForEach(c => c.Width = c.Width + 1);
wb.SaveAs("output.xlsx");
執行結果。
【2024-05-14 補充】
因有讀者敲碗,再補上 Excel 轉 JSON 範例。.NET Framework + Json.NET 版本:
static void Main(string[] args)
{
var wb = new XLWorkbook("sample.xlsx");
var ws = wb.Worksheet(1);
var headerRow = ws.Row(1);
var headers = headerRow.Cells().Select(cell => cell.Value.ToString()).ToList();
var data = new JArray();
var rows = ws.RowsUsed().Skip(1);
foreach (var row in rows)
{
var rowData = new JObject();
for (int i = 0; i < headers.Count; i++)
{
var cell = row.Cell(i + 1);
if (cell.Value.IsNumber)
rowData[headers[i]] = cell.Value.GetNumber();
else if (cell.Value.IsDateTime)
rowData[headers[i]] = cell.Value.GetDateTime();
else
rowData[headers[i]] = cell.Value.ToString();
}
data.Add(rowData);
}
var json = JsonConvert.SerializeObject(data, Formatting.Indented);
File.WriteAllText("output.json", json);
}
.NET 6+ + System.Text.Json 版本。
using ClosedXML.Excel;
using System.Text.Json;
using System.IO;
using System.Text.Json.Nodes;
var wb = new XLWorkbook("sample.xlsx");
var ws = wb.Worksheet(1);
var headerRow = ws.Row(1);
var headers = headerRow.Cells().Select(cell => cell.Value.ToString()).ToList();
var data = new JsonArray();
var rows = ws.RowsUsed().Skip(1);
foreach (var row in rows)
{
var rowData = new JsonObject();
for (int i = 0; i < headers.Count; i++)
{
var cell = row.Cell(i + 1);
if (cell.Value.IsNumber)
rowData[headers[i]] = cell.Value.GetNumber();
else if (cell.Value.IsDateTime)
rowData[headers[i]] = cell.Value.GetDateTime();
else
rowData[headers[i]] = cell.Value.ToString();
}
data.Add(rowData);
}
var options = new JsonSerializerOptions
{
WriteIndented = true
};
var json = JsonSerializer.Serialize(data, options);
File.WriteAllText("output.json", json);
.NET Framework and .NET 6+ examples to convert JSON to Excel with ClosedXML.
Comments
# by ezAI
太棒了 感謝喔
# by testr
powershell 安装importexcel模块后,可以直接export-excel。虽然有些跑题