| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252 |
- using Aspose.Words;
- using Aspose.Words.Tables;
- using System.Text.Json;
- using System.Text.Json.Serialization;
- public static class JsonToWordHelper
- {
- public static byte[] ConvertJsonToWord(string json)
- {
- if (string.IsNullOrWhiteSpace(json))
- throw new ArgumentException("JSON不能为空", nameof(json));
- var model = System.Text.Json.JsonSerializer.Deserialize<TripDocumentModel>(json, new JsonSerializerOptions
- {
- PropertyNameCaseInsensitive = true
- });
- if (model == null)
- throw new InvalidOperationException("JSON反序列化失败");
- model.Sections ??= new List<TripSection>();
- model.Closing ??= new List<string>();
- var doc = new Document();
- var builder = new DocumentBuilder(doc);
- SetDefaultFont(builder);
- // 标题
- builder.ParagraphFormat.ClearFormatting();
- builder.ParagraphFormat.Alignment = ParagraphAlignment.Center;
- builder.Font.Bold = true;
- builder.Font.Size = 16;
- builder.Writeln(model.Title ?? string.Empty);
- builder.InsertParagraph();
- // 收文单位
- builder.ParagraphFormat.ClearFormatting();
- builder.ParagraphFormat.Alignment = ParagraphAlignment.Left;
- builder.Font.Bold = false;
- builder.Font.Size = 12;
- builder.Writeln($"{model.Receiver}:");
- // 引言
- WriteNormalParagraph(builder, model.Intro);
- // 正文 sections
- foreach (var section in model.Sections)
- {
- if (!string.IsNullOrWhiteSpace(section.Title))
- {
- builder.ParagraphFormat.ClearFormatting();
- builder.ParagraphFormat.Alignment = ParagraphAlignment.Left;
- builder.Font.Bold = true;
- builder.Font.Size = 12;
- builder.Writeln(section.Title);
- }
- if (string.Equals(section.Type, "table", StringComparison.OrdinalIgnoreCase))
- {
- WriteTable(builder, section.Table);
- builder.InsertParagraph();
- continue;
- }
- if (section.Items != null && section.Items.Count > 0)
- {
- for (int i = 0; i < section.Items.Count; i++)
- {
- var item = section.Items[i];
- WriteNormalParagraph(builder, $"{i + 1}. {item.Title}");
- if (item.Content != null)
- {
- foreach (var line in item.Content)
- {
- WriteNormalParagraph(builder, line);
- }
- }
- }
- }
- else if (section.Content != null && section.Content.Count > 0)
- {
- foreach (var line in section.Content)
- {
- WriteNormalParagraph(builder, line);
- }
- }
- builder.InsertParagraph();
- }
- // 结尾
- foreach (var line in model.Closing)
- {
- WriteNormalParagraph(builder, line);
- }
- builder.InsertParagraph();
- // 落款
- builder.ParagraphFormat.ClearFormatting();
- builder.ParagraphFormat.Alignment = ParagraphAlignment.Right;
- builder.Font.Bold = false;
- builder.Font.Size = 12;
- builder.Writeln(model.Signature ?? string.Empty);
- builder.Writeln(model.Date ?? string.Empty);
- using var ms = new MemoryStream();
- doc.Save(ms, SaveFormat.Docx);
- return ms.ToArray();
- }
- private static void WriteNormalParagraph(DocumentBuilder builder, string? text)
- {
- if (string.IsNullOrWhiteSpace(text))
- return;
- builder.ParagraphFormat.ClearFormatting();
- builder.ParagraphFormat.Alignment = ParagraphAlignment.Left;
- builder.ParagraphFormat.FirstLineIndent = 24; // 首行缩进,约2字符
- builder.ParagraphFormat.SpaceAfter = 6;
- builder.Font.Bold = false;
- builder.Font.Size = 12;
- builder.Writeln(text.Trim());
- }
- private static void WriteTable(DocumentBuilder builder, TripTable? table)
- {
- if (table?.Headers == null || table.Headers.Count == 0)
- return;
- var colCount = table.Headers.Count;
- builder.StartTable();
- // 表头
- foreach (var header in table.Headers)
- {
- builder.InsertCell();
- builder.CellFormat.VerticalAlignment = CellVerticalAlignment.Center;
- builder.ParagraphFormat.Alignment = ParagraphAlignment.Center;
- builder.Font.Bold = true;
- builder.Write(header ?? string.Empty);
- }
- builder.EndRow();
- // 数据
- if (table.Rows != null)
- {
- foreach (var row in table.Rows)
- {
- var safeRow = row ?? new List<string>();
- for (int i = 0; i < colCount; i++)
- {
- builder.InsertCell();
- builder.CellFormat.VerticalAlignment = CellVerticalAlignment.Center;
- builder.ParagraphFormat.Alignment = ParagraphAlignment.Center;
- builder.Font.Bold = false;
- var cellText = i < safeRow.Count ? safeRow[i] ?? string.Empty : string.Empty;
- builder.Write(cellText);
- }
- builder.EndRow();
- }
- }
- var wordTable = builder.EndTable();
- // 表格样式
- wordTable.AutoFit(AutoFitBehavior.AutoFitToWindow);
- foreach (Row row in wordTable.Rows)
- {
- foreach (Cell cell in row.Cells)
- {
- cell.CellFormat.LeftPadding = 5;
- cell.CellFormat.RightPadding = 5;
- cell.CellFormat.TopPadding = 3;
- cell.CellFormat.BottomPadding = 3;
- }
- }
- }
- private static void SetDefaultFont(DocumentBuilder builder)
- {
- builder.Font.Name = "宋体";
- builder.Font.Size = 12;
- }
- }
- public class TripDocumentModel
- {
- [JsonPropertyName("title")]
- public string? Title { get; set; }
- [JsonPropertyName("receiver")]
- public string? Receiver { get; set; }
- [JsonPropertyName("intro")]
- public string? Intro { get; set; }
- [JsonPropertyName("sections")]
- public List<TripSection>? Sections { get; set; }
- [JsonPropertyName("closing")]
- public List<string>? Closing { get; set; }
- [JsonPropertyName("signature")]
- public string? Signature { get; set; }
- [JsonPropertyName("date")]
- public string? Date { get; set; }
- }
- public class TripSection
- {
- [JsonPropertyName("type")]
- public string? Type { get; set; }
- [JsonPropertyName("title")]
- public string? Title { get; set; }
- [JsonPropertyName("items")]
- public List<TripItem>? Items { get; set; }
- [JsonPropertyName("content")]
- public List<string>? Content { get; set; }
- [JsonPropertyName("table")]
- public TripTable? Table { get; set; }
- }
- public class TripItem
- {
- [JsonPropertyName("title")]
- public string? Title { get; set; }
- [JsonPropertyName("content")]
- public List<string>? Content { get; set; }
- }
- public class TripTable
- {
- [JsonPropertyName("headers")]
- public List<string>? Headers { get; set; }
- [JsonPropertyName("rows")]
- public List<List<string>>? Rows { get; set; }
- }
|