【实用技能】如何在 .NET C# 中的邮件合并过程中操作表格单元格

TX Text Control 中的邮件合并 类是一个强大的库,旨在通过将数据合并到模板中来自动创建文档。它充当结构化数据(例如来自数据库、JSON 或 XML)和动态文档生成之间的桥梁,对于需要自动化文档工作流程的应用程序来说非常有用。

TX Text Control 最新版试用下载

从本质上讲,MailMerge 类简化了创建专业、数据驱动文档的复杂任务,允许开发人员轻松地将模板中的字段与数据源合并。模板是使用 TX Text Control 文字处理界面设计的,合并字段代表动态内容。

合并区块

合并块是 TX Text Control 的 MailMerge 类中的一个关键概念,它允许在文档中动态生成结构化、可重复的内容。合并块允许开发人员有效地处理模板中的重复数据结构,例如列表、表格或嵌套区域。

从高层次上讲,合并块是模板中定义的部分,对应于数据集合或数据表。在合并过程中,MailMerge 会遍历数据源,动态创建每条记录的内容。这些合并块可以使用 MailMerge 类的现成功能进行有条件的呈现、过滤和排序。

代码级操作

但是 MailMerge 类还允许在合并过程中进行非常详细的代码级操作。这包括处理合并事件、自定义合并过程以及以编程方式控制合并操作的输出。这种级别的控制对于需要对合并过程进行细粒度控制的复杂文档生成场景至关重要。

本文介绍如何使用“字段合并” 事件来操作合并字段位于表格单元格内时由事件返回的表格单元格。在本例中,我们将使用一个非常简单的模板,该模板由两个合并字段和一个用红色突出显示的简单重复块组成。

TX 文本控件中的邮件合并模板

为了合并模板,我们将使用以下简化的 JSON 数据。

[
  {
    "invoice-id": "1",
    "invoice-date": "2019-01-01",
    "line-items": [
      {
        "product-id": "1",
        "quantity": "1",
        "unit-price": "8"
      },
      {
        "product-id": "2",
        "quantity": "2",
        "unit-price": "200"
      },
      {
        "product-id": "3",
        "quantity": "1",
        "unit-price": "100"
      },
      {
        "product-id": "4",
        "quantity": "1",
        "unit-price": "3"
      }
    ]
  }
]

为了合并此模板,将使用以下代码:

textControl1.Load("template.tx", TXTextControl.StreamType.InternalUnicodeFormat);
MailMerge mailMerge = new MailMerge();
mailMerge.TextComponent = textControl1;
string jsonData = File.ReadAllText("data.json");
mailMerge.MergeJsonData(jsonData);

合并后的文档结果如下:

TX 文本控件中的合并文档

FieldMerged 事件

现在让我们附加 FieldMerged 事件来操作合并过程。

textControl1.Load("template.tx", TXTextControl.StreamType.InternalUnicodeFormat);
MailMerge mailMerge = new MailMerge();
mailMerge.TextComponent = textControl1;
mailMerge.FieldMerged += MailMerge_FieldMerged;
string jsonData = File.ReadAllText("data.json");
mailMerge.MergeJsonData(jsonData);

每次合并字段时(成功或失败),都会调用此事件。如果字段位于表格单元格内,则返回表格单元格。

在此事件中,我们检查TableCell属性是否不为空。如果不为空,我们将设置单元格的背景颜色。

private void MailMerge_FieldMerged(object sender, MailMerge.FieldMergedEventArgs e)
{
  if (e.TableCell != null)
  {
      e.TableCell.CellFormat.BackColor = Color.Red;
      e.TableCell.CellFormat.BottomBorderWidth = 60;
      e.TableCell.CellFormat.BottomBorderColor = Color.Blue;
  }
}

因此,合并过程中所有合并的单元格都会被着色。

TX 文本控件中带有彩色单元格的合并文档

动态单元格颜色

让我们通过添加一些逻辑使这个过程动态化。CellFilterInstructions类用于将一个值与给定值进行比较以返回特定的颜色。

using System;
using System.Drawing;
using System.Linq;
public class CellFilterInstructions
{
   public double? CompareValue { get; set; } = null;
   public RelationalOperator? Operator { get; set; } = null;
   public Color TrueColor { get; set; } = Color.White;
   public Color FalseColor { get; set; } = Color.White;
   public enum RelationalOperator
   {
       Equals = 0,
       NotEqual,
       LessThan,
       GreaterThan,
   }
   // evaluates the instruction and returns the proper color
   public Color? GetColor(string value)
   {
       if (Double.TryParse(ParseToNumber(value), out double dValue) == true)
       {
           switch (Operator)
           {
               case RelationalOperator.Equals:
                   return (dValue == CompareValue ? TrueColor : FalseColor);
               case RelationalOperator.NotEqual:
                   return (dValue != CompareValue ? TrueColor : FalseColor);
               case RelationalOperator.GreaterThan:
                   return (dValue > CompareValue ? TrueColor : FalseColor);
               case RelationalOperator.LessThan:
                   return (dValue < CompareValue ? TrueColor : FalseColor);
               default:
                   return null;
           }
       }
       else
           return null;
   }
 private string ParseToNumber(string text)
   {
       var numericChars = "0123456789,.".ToCharArray();
       return new String(text.Where(c => numericChars.Any(n => n == c)).ToArray());
   }
}

以下代码创建了一条新规则,如果值大于 10,则返回绿色,如果值小于 10,则返回红色。此规则被序列化并存储在表单元格的Name属性中。

textControl1.Load("template.tx", TXTextControl.StreamType.InternalUnicodeFormat);
CellFilterInstructions cellFilterInstructions = new CellFilterInstructions() {
   CompareValue = 10,
   Operator = CellFilterInstructions.RelationalOperator.GreaterThan,
   TrueColor = Color.Green,
   FalseColor = Color.Red
};
textControl1.Tables[1].Cells[2,2].Name =
 JsonConvert.SerializeObject(cellFilterInstructions);
MailMerge mailMerge = new MailMerge();
mailMerge.TextComponent = textControl1;
mailMerge.FieldMerged += MailMerge_FieldMerged;
string jsonData = File.ReadAllText("data.json");
mailMerge.MergeJsonData(jsonData);

在FieldMerged事件中,此规则被放弃并评估。然后,返回的颜色将应用于表格单元格的表格单元格格式。

private void MailMerge_FieldMerged(object sender, MailMerge.FieldMergedEventArgs e)
{
   // custom field handling
   if (e.TableCell == null)
       return;
   if (e.TableCell.Name != "")
   {
       CellFilterInstructions instructions =
           (CellFilterInstructions)JsonConvert.DeserializeObject(
               e.TableCell.Name,
               typeof(CellFilterInstructions));
       // retrieve the color
       Color? color = instructions.GetColor(e.MailMergeFieldAdapter.ApplicationField.Text);
       // apply the color
       if (color != null)
           e.TableCell.CellFormat.BackColor = (Color)color;
   }
}

以下屏幕截图显示了此合并过程的结果:

TX 文本控件中带有条件单元格颜色的合并文档

结论

TX Text Control 中的 MailMerge 类为自动化文档生成过程提供了强大而灵活的解决方案。使用合并块和代码级操作,开发人员可以轻松创建动态、数据驱动的文档。FieldMerged 事件对合并过程提供了细粒度的控制,允许开发人员根据特定条件自定义输出。这种级别的控制对于需要精确处理数据和内容的复杂文档生成场景至关重要。

上一篇:16、PyTorch中进行卷积残差模块算子融合


下一篇:.NET应用UI框架DevExpress XAF v24.2新功能预览 - 跨平台性增强