[英]Create a table with Variable Columns in OpenXML
我有一個包含每個 object 結構的列表,如下所示
{
"regionName": "(R1)",
"physicalRules": [
{
"region": "(R1)",
"Group": "Strip_10",
"ClassGroup": "DKC",
"properties": [
{
"name": "N1",
"value": "200"
},
{
"name": "N2",
"value": "14"
}
]
}
]
}
我想創建一個表結構如下
-----------------------------------------------------
(R1) (R2) (R3)
N1 N2 N3 N4 N5 N6
200 14 5 10 15 500
其中 R1、R2 和 R3 數據中的每一個都是具有上述結構的對象的形式。 僅顯示 R1 以避免重復,因為 R2 和 R3 具有相似的結構。 這實際上意味着表的列數由列表中的對象數定義。 我不確定如何在 OpenXML 表中動態創建列。 我看到的所有示例都是在 OpenXML 表中添加固定數量的列。我應該為每個對象創建一個單獨的表並按列垂直連接它們嗎? 我也不知道該怎么做。
private void AddTable(Body body, MyVM 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 };
// Apply
tableProp.Append(tableStyle, tableWidth);
tbl.AppendChild(tableProp);
// Add 3 columns to the table.
TableGrid tg = new(new GridColumn(), new GridColumn(), new GridColumn());
tbl.AppendChild(tg);
foreach (var item in data)
{
TableRow tr1 = new();
TableCell tc1 = new(new Paragraph(new Run(new Text(item.FirstName))));
TableCell tc2 = new(new Paragraph(new Run(new Text(item.LastName))));
TableCell tc3 = new(new Paragraph(new Run(new Text($"{item.Age}"))));
tr1.Append(tc1, tc2, tc3);
tbl.AppendChild(tr1);
}
body.AppendChild(tbl);
}
根據您的示例 JSON,我假設您的 model 類將如下所示:
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
}
}
這是我得到的 output:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.