我有一个包含每个对象结构的列表,如下
^8.2.10
我想创建如下表结构
{
"regionName": "(R1)",
"physicalRules": [
{
"region": "(R1)",
"Group": "Strip_10",
"ClassGroup": "DKC",
"properties": [
{
"name": "N1",
"value": "200"
},
{
"name": "N2",
"value": "14"
}
]
}
]
}
其中 R1、R2 和 R3 数据中的每一个都是具有上述定义结构的对象形式。仅显示 R1 以避免重复,因为 R2 和 R3 具有相似的结构。这实际上意味着表的列数由列表中的对象数定义。我不确定如何在 OpenXML 表中动态创建列。我看到的所有示例都向 OpenXML 表添加了固定数量的列。我应该为每个对象创建一个单独的表并按列垂直连接它们吗?我也不知道该怎么做。
-----------------------------------------------------
(R1) (R2) (R3)
N1 N2 N3 N4 N5 N6
200 14 5 10 15 500
答案 0 :(得分:1)
根据您的示例 JSON,我假设您的模型类如下所示:
public class Item
{
public string RegionName { get; set; }
public List<PhysicalRule> PhysicalRules { get; set; }
}
public class PhysicalRule
{
public string Region { get; set; }
public string Group { get; set; }
public string ClassGroup { get; set; }
public List<Property> Properties { get; set; }
}
public class Property
{
public string Name { get; set; }
public string Value { get; set; }
}
您可以使用以下方法生成表格:
private static void AddTable(Body body, List<Item> data)
{
Table tbl = new();
// Set the style and width for the table.
TableProperties tableProp = new();
TableStyle tableStyle = new() { Val = "TableGrid" };
// Make the table width 100% of the page width.
TableWidth tableWidth = new() { Width = "5000", Type = TableWidthUnitValues.Pct };
tableProp.Append(tableStyle, tableWidth);
TableGrid tableGrid = new(); // we will fill this as we go
// We will create three rows simultaneously, with a variable number of columns in them
TableRow regionsRow = new();
TableRow propertyNamesRow = new();
TableRow propertyValuesRow = new();
tbl.Append(tableProp, tableGrid, regionsRow, propertyNamesRow, propertyValuesRow);
int colsAdded = 0;
foreach (var rule in data.SelectMany(i => i.PhysicalRules))
{
var count = rule.Properties.Count;
if (count > 0)
{
TableCell regionCell = new();
// If there's more than one property in the rule,
// make the region cell span across those columns
if (count > 1)
{
TableCellProperties cellProperties = new();
cellProperties.Append(new GridSpan { Val = count });
regionCell.Append(cellProperties);
}
regionCell.Append(new Paragraph(new Run(new Text(rule.Region))));
regionsRow.Append(regionCell);
// Create one column for each property and add
// the name and value to the the respective rows
foreach (var prop in rule.Properties)
{
tableGrid.Append(new GridColumn());
colsAdded++;
TableCell nameCell = new();
nameCell.Append(new Paragraph(new Run(new Text(prop.Name))));
propertyNamesRow.Append(nameCell);
TableCell valueCell = new();
valueCell.Append(new Paragraph(new Run(new Text(prop.Value))));
propertyValuesRow.Append(valueCell);
}
}
}
// Don't add the table unless there's something in it
if (colsAdded > 0) body.AppendChild(tbl);
}
这是我用来测试上述内容的程序。我从一个空白文档开始,它被保存到“Blank.docx”。该程序将此文件复制到不同的名称,然后使用 OpenXml 对其进行修改。我相信这与您所说的流程相同。
using System.Collections.Generic;
using System.IO;
using System.Linq;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
public class Program
{
public static void Main(string[] args)
{
string filename = "Output.docx";
File.Copy("Blank.docx", filename, true);
using (WordprocessingDocument doc = WordprocessingDocument.Open(filename, true))
{
var body = doc.MainDocumentPart.Document.Body;
var items = GetItems();
AddTable(body, items);
doc.Save();
doc.Close();
}
}
private static List<Item> GetItems()
{
var items = new List<Item>
{
new Item
{
RegionName = "(R1)",
PhysicalRules = new List<PhysicalRule>
{
new PhysicalRule
{
Region = "(R1)",
Group = "Strip_10",
ClassGroup = "DKC",
Properties = new List<Property>
{
new Property { Name = "N1", Value = "200" },
new Property { Name = "N2", Value = "14" }
}
}
}
},
new Item
{
RegionName = "(R2)",
PhysicalRules = new List<PhysicalRule>
{
new PhysicalRule
{
Region = "(R2)",
Group = "Strip_10",
ClassGroup = "DKC",
Properties = new List<Property>
{
new Property { Name = "N3", Value = "5" },
new Property { Name = "N4", Value = "10" },
new Property { Name = "N5", Value = "15" }
}
}
}
},
new Item
{
RegionName = "(R3)",
PhysicalRules = new List<PhysicalRule>
{
new PhysicalRule
{
Region = "(R3)",
Group = "Strip_10",
ClassGroup = "DKC",
Properties = new List<Property>
{
new Property { Name = "N6", Value = "500" }
}
}
}
}
};
return items;
}
private static void AddTable(Body body, List<Item> data)
{
// code as shown earlier in my answer
}
}
这是我得到的输出: