簡體   English   中英

在 OpenXML 中創建包含變量列的表

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM