Neste artigo, mostrarei como executar a mala direta do MS Word usando C# ou VB.NET sem o MS Word ou Office Interop. Aspose.Words for .NET é uma API do Word rica em recursos e poderosa que fornece todos os recursos básicos e estendidos do MS Word Mail Merge. Ele permite gerar cartas, envelopes, relatórios, faturas e outros tipos de documentos em Windows Forms, aplicativos Web ASP.NET ou qualquer aplicativo .NET/.NET Core.

Cobrindo os principais recursos de nossa API de mala direta .NET, este artigo é composto pelas seguintes seções:

O que é mala direta?

Mail Merge é a forma de geração automatizada de relatórios, cartas, envelopes, faturas e outros tipos de documentos. A mala direta no MS Word permite que você crie um documento de modelo contendo campos de mesclagem e preencha esses campos usando registros na fonte de dados. Para entender a Mala Direta, suponha que você tenha que enviar uma carta para dez pessoas diferentes e apenas o nome e os campos de endereço devem ser atualizados. Nesse caso, basta criar um modelo da carta e, em seguida, gerar as cartas dinamicamente, preenchendo os campos de mesclagem de nome e endereço usando a fonte de dados.

Fontes de dados para mala direta

Os dados da mala direta podem ser obtidos de qualquer fonte de dados, como XML, JSON ou um banco de dados. No que diz respeito ao Aspose.Words for .NET, você pode usar qualquer fonte de dados que seja suportada pelo ADO.NET. Os dados podem ser carregados em um DataSet, DataTable, DataView ou uma matriz de valores.

Preparando o modelo para mala direta

O modelo de mala direta é o documento que contém os campos de mesclagem. Esses campos são preenchidos com os dados na fonte de dados quando a mala direta é executada. O documento de modelo não precisa ser um formato de modelo e pode ser um documento DOC/DOCX. É assim que você pode preparar um modelo para mala direta.

  • Abra seu documento ou crie um novo no MS Word.
  • Coloque o cursor onde você deseja adicionar um campo de mesclagem.
  • No menu Inserir, selecione a opção Campo.
  • Na lista Nomes de campo, selecione MergeField.
  • Insira um nome para o campo de mesclagem em Nome do campo e pressione OK.
  • Salve o documento.

A seguir está a captura de tela do documento modelo de amostra.

Modelo de mala direta

API de mala direta .NET - Instalação

O Aspose.Words for .NET pode ser baixado ou instalado das seguintes maneiras:

Executar mala direta no documento do Word usando C#

Depois de ter o modelo pronto, você pode executar a Mala Direta para gerar os documentos. A seguir estão as etapas para executar a mala direta no modelo mencionado acima.

O exemplo de código a seguir mostra como executar a mala direta do MS Word usando uma matriz de valores em C#.

// Para exemplos completos e arquivos de dados, acesse https://github.com/aspose-words/Aspose.Words-for-.NET
// O caminho para o diretório de documentos.
string dataDir = RunExamples.GetDataDir_MailMergeAndReporting(); 
// Abra um documento existente.
Document doc = new Document(dataDir + "MailMerge.ExecuteArray.doc");

// Aparar valores de mala direta de espaços em branco à direita e à esquerda
doc.MailMerge.TrimWhitespaces = false;

// Preencha os campos do documento com os dados do usuário.
doc.MailMerge.Execute(
    new string[] { "FullName", "Company", "Address", "Address2", "City" },
    new object[] { "James Bond", "MI5 Headquarters", "Milbank", "", "London" });

dataDir = dataDir + "MailMerge.ExecuteArray_out.doc";
// Envie o documento em formato Word para o navegador cliente com a opção de salvar em disco ou abrir dentro do navegador atual.
doc.Save(dataDir);

Documento do Word após a mala direta

Executar mala direta em C#

Executar mala direta usando fonte de dados XML em C#

Os arquivos XML são amplamente utilizados para guardar e importar/exportar dados. Aspose.Words for .NET também oferece suporte a XML como fonte de dados para mala direta. Basta ler o XML em um objeto DataSet e executar a mala direta. A seguir está o arquivo XML de amostra que vamos usar.

<customers>
<customer Name="John Ben Jan" ID="1" Domain="History" City="Boston"/>
<customer Name="Lisa Lane" ID="2" Domain="Chemistry" City="LA"/>
<customer Name="Dagomir Zits" ID="3" Domain="Heraldry" City="Milwaukee"/>
<customer Name="Sara Careira Santy" ID="4" Domain="IT" City="Miami"/>
</customers>

O exemplo de código a seguir busca os dados de uma fonte de dados XML e executa a mala direta usando C#.

// Para exemplos completos e arquivos de dados, acesse https://github.com/aspose-words/Aspose.Words-for-.NET
// O caminho para o diretório de documentos.
string dataDir = RunExamples.GetDataDir_MailMergeAndReporting(); 

// Crie o Dataset e leia o XML.
DataSet customersDs = new DataSet();
customersDs.ReadXml(dataDir + "Customers.xml");

string fileName = "TestFile XML.doc";
// Abra um documento modelo.
Document doc = new Document(dataDir + fileName);

// Execute a mala direta para preencher o modelo com dados de XML usando DataTable.
doc.MailMerge.Execute(customersDs.Tables["Customer"]);

dataDir = dataDir + RunExamples.GetOutputFilePath(fileName);
// Salve o documento de saída.
doc.Save(dataDir);

Abaixo está a mala direta modelo que será preenchida com dados XML.

Modelo de mala direta para XML

A seguir está a página 1 do documento do Word resultante que obtemos após a execução da mala direta.

Executar mala direta com XML em C#

Formatação personalizada de campos de mesclagem

Aspose.Words for .NET lhe dá mais controle sobre a Mala Direta durante a execução. A propriedade MailMerge.FieldMergingCallback permite que você personalize a mala direta quando qualquer campo de mesclagem for encontrado. MailMerge.FieldMergingCallback aceita a classe que implementa os métodos IFieldMergingCallback.FieldMerging e IFieldMergingCallback.ImageFieldMerging.

O exemplo de código a seguir mostra como personalizar a operação de mala direta e aplicar formatação às células dentro de este modelo.

// Para exemplos completos e arquivos de dados, acesse https://github.com/aspose-words/Aspose.Words-for-.NET
// O caminho para o diretório de documentos.
string dataDir = RunExamples.GetDataDir_MailMergeAndReporting(); 
Document doc = new Document(dataDir + "MailMerge.AlternatingRows.doc");

// Adicione um manipulador para o evento MergeField.
doc.MailMerge.FieldMergingCallback = new HandleMergeFieldAlternatingRows();

// Execute mala direta com regiões.
DataTable dataTable = GetSuppliersDataTable();
doc.MailMerge.ExecuteWithRegions(dataTable);
dataDir = dataDir + "MailMerge.AlternatingRows_out.doc";
doc.Save(dataDir);

Veja a seguir a implementação da classe HandleMergeFieldAlternatingRows.

// Para exemplos completos e arquivos de dados, acesse https://github.com/aspose-words/Aspose.Words-for-.NET
private class HandleMergeFieldAlternatingRows : IFieldMergingCallback
{
    ///<summary>
    /// Chamado para cada campo de mesclagem encontrado no documento.
    /// Podemos retornar alguns dados ao mecanismo de mala direta ou fazer algo
    /// Senão com o documento. Neste caso, modificamos a formatação da célula.
    ///</summary>
    void IFieldMergingCallback.FieldMerging(FieldMergingArgs e)
    {
        if (mBuilder == null)
            mBuilder = new DocumentBuilder(e.Document);

        // Desta forma, pegamos o início de uma nova linha.
        if (e.FieldName.Equals("CompanyName"))
        {
            // Selecione a cor dependendo se o número da linha é par ou ímpar.
            Color rowColor;
            if (IsOdd(mRowIdx))
                rowColor = Color.FromArgb(213, 227, 235);
            else
                rowColor = Color.FromArgb(242, 242, 242);

            // Não há como definir as propriedades da célula para a linha inteira no momento,
            // Portanto, temos que iterar sobre todas as células da linha.
            for (int colIdx = 0; colIdx < 4; colIdx++)
            {
                mBuilder.MoveToCell(0, mRowIdx, colIdx, 0);
                mBuilder.CellFormat.Shading.BackgroundPatternColor = rowColor;
            }

            mRowIdx++;
        }
    }

    void IFieldMergingCallback.ImageFieldMerging(ImageFieldMergingArgs args)
    {
        // Fazer nada.
    }

    private DocumentBuilder mBuilder;
    private int mRowIdx;
}     
///<summary>
/// Retorna verdadeiro se o valor for ímpar; false se o valor for par.
///</summary>
private static bool IsOdd(int value)
{
    // O código é um pouco complexo, mas a conversão automática para VB não funciona.
    return ((value / 2) * 2).Equals(value);
}      
///<summary>
/// Criar DataTable e preenchê-lo com dados.
/// Na vida real esta DataTable deve ser preenchida a partir de um banco de dados.
///</summary>
private static DataTable GetSuppliersDataTable()
{
    DataTable dataTable = new DataTable("Suppliers");
    dataTable.Columns.Add("CompanyName");
    dataTable.Columns.Add("ContactName");
    for (int i = 0; i < 10; i++)
    {
        DataRow datarow = dataTable.NewRow();
        dataTable.Rows.Add(datarow);
        datarow[0] = "Company " + i.ToString();
        datarow[1] = "Contact " + i.ToString();
    }
    return dataTable;
}

Mala direta com regiões usando C#

Pode haver o caso de você precisar preencher e repetir uma região específica no documento do Word. Nesse caso, você pode usar a mala direta com regiões. Para criar uma região, você precisa especificar o início e o fim da região e, em seguida, o Mail Megre repetirá essa região para cada registro na fonte de dados. Por exemplo, o modelo a seguir contém duas regiões, Orders e OrderDetails com os campos de mesclagem «TableStart:Orders», «TableEnd:Orders» e «TableStart:OrderDetails», «TableEnd:OrderDetails» respectivamente.

Mala direta com regiões

A seguir está o exemplo de código que executa Mail Megre em regiões para o modelo mencionado acima.

// Para exemplos completos e arquivos de dados, acesse https://github.com/aspose-words/Aspose.Words-for-.NET
// O caminho para o diretório de documentos.
string dataDir = RunExamples.GetDataDir_MailMergeAndReporting();
string fileName = "MailMerge.ExecuteWithRegions.doc";
Document doc = new Document(dataDir + fileName);
 
// Use DataTable como uma fonte de dados.
int orderId = 10444;
DataTable orderTable = GetTestOrder(orderId);
doc.MailMerge.ExecuteWithRegions(orderTable);
 
// Em vez de usar DataTable, você pode criar um DataView para classificação ou filtro personalizado e, em seguida, mala direta.
DataView orderDetailsView = new DataView(GetTestOrderDetails(orderId));
orderDetailsView.Sort = "ExtendedPrice DESC";
 
// Execute a operação de mala direta.
doc.MailMerge.ExecuteWithRegions(orderDetailsView);
 
// Salve o documento mesclado.
dataDir = dataDir + RunExamples.GetOutputFilePath(fileName);
doc.Save(dataDir);

A seguir estão os métodos para ler dados do banco de dados.

// Para exemplos completos e arquivos de dados, acesse https://github.com/aspose-words/Aspose.Words-for-.NET
private static DataTable GetTestOrder(int orderId)
{
    DataTable table = ExecuteDataTable(string.Format(
        "SELECT * FROM AsposeWordOrders WHERE OrderId = {0}", orderId));
    table.TableName = "Orders";
    return table;
}
private static DataTable GetTestOrderDetails(int orderId)
{
    DataTable table = ExecuteDataTable(string.Format(
        "SELECT * FROM AsposeWordOrderDetails WHERE OrderId = {0} ORDER BY ProductID", orderId));
    table.TableName = "OrderDetails";
    return table;
}
///<summary>
/// Função de utilitário que cria uma conexão, comando, 
/// Executa o comando e retorna o resultado em uma DataTable.
///</summary>
private static DataTable ExecuteDataTable(string commandText)
{
    // Abra a conexão do banco de dados.
    string connString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" +
        RunExamples.GetDataDir_Database() + "Northwind.mdb";
    OleDbConnection conn = new OleDbConnection(connString);
    conn.Open();

    // Crie e execute um comando.
    OleDbCommand cmd = new OleDbCommand(commandText, conn);
    OleDbDataAdapter da = new OleDbDataAdapter(cmd);
    DataTable table = new DataTable();
    da.Fill(table);

    // Feche o banco de dados.
    conn.Close();

    return table;
}

Regiões de mala direta aninhadas

Na maioria das vezes, os dados que temos na fonte de dados vêm na forma de relacionamentos. Por exemplo, a tabela “Order” terá um relacionamento um-para-muitos com os “OrderDetails” que manterão registros dos itens em um pedido. Para lidar com esses relacionamentos pai-filho, a Mala Direta aninhada é usada. Veja a seguir um modelo de fatura que se adequa bem a esse cenário.

Modelo de mala direta com regiões

Veja a seguir a fonte de dados XML de exemplo que usaremos para a mala direta aninhada.

<?xml version="1.0" encoding="utf-8"?>
<Orders xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="OrdersSchema.xsd">
  <Order>
    <Number>23</Number>
    <Address>Nelson Street</Address>
    <Suburb>Howick</Suburb>
    <City>Auckland</City>
    <Phonenumber>543 1234</Phonenumber>
    <Date>03/01/2010</Date>
    <Total>14.00</Total>
    <Item>
      <Name>BBQ Chicken Pizza</Name>
      <Price>6.00</Price>
      <Quantity>1</Quantity>
      <ItemTotal>6.00</ItemTotal>
    </Item>
    <Item>
      <Name>1.5 Litre Coke</Name>
      <Price>4.00</Price>
      <Quantity>2</Quantity>
      <ItemTotal>8.00</ItemTotal>
    </Item>
  </Order>
  <Order>
    <Number>10</Number>
    <Address>Parkville Avenue</Address>
    <Suburb>Pakuranga</Suburb>
    <City>Auckland</City>
    <Phonenumber>548 7342</Phonenumber>
    <Date>05/03/2010</Date>
    <Total>6.00</Total>
    <Item>
      <Name>Hawaiian Pizza</Name>
      <Price>4.00</Price>
      <Quantity>1</Quantity>
      <ItemTotal>4.00</ItemTotal>
    </Item>
    <Item>
      <Name>Fries</Name>
      <Price>1.00</Price>
      <Quantity>2</Quantity>
      <ItemTotal>2.00</ItemTotal>
    </Item>
  </Order>
</Orders>

Considerando que, o OrderSchema.xsd para este XML é:

<?xml version="1.0" encoding ="utf-8"?>
<xs:schema id="OrdersSchema"  xmlns:xs="http://www.w3.org/2001/XMLSchema">
 <xs:element name="Orders">
 <xs:complexType>
 <xs:sequence>
  <xs:element name="Order">
  <xs:complexType>
  <xs:sequence>
  <xs:element name="Number"/>
  <xs:element name="Address"/>
  <xs:element name="Suburb"/>
  <xs:element name="City"/>
  <xs:element name="Phonenumber">
  <xs:element name="Date"/>
  <xs:element name="Total"/>
  <xs:element name="Item">
   <xs:complexType>
   <xs:sequence>
   <xs:element name="Name"/>
   <xs:element name="Price"/>
   <xs:element name="Quantity"/>
   <xs:element name="ItemTotal"/>
   </xs:sequence>
  </xs:complexType>
  </xs:element>
  </xs:sequence>
  </xs:complexType>
 </xs:element>
 </xs:sequence>
 </xs:complexType>
 </xs:element>
</xs:schema>

O exemplo de código a seguir é usado para executar a mala direta aninhada usando C#.

// Para exemplos completos e arquivos de dados, acesse https://github.com/aspose-words/Aspose.Words-for-.NET
// O caminho para o diretório de documentos.
string dataDir = RunExamples.GetDataDir_MailMergeAndReporting(); 
	 
// Crie o Dataset e leia o XML.
DataSet pizzaDs = new DataSet();
	 
// O Datatable.TableNames e o DataSet.Relations são definidos implicitamente pelo .NET por meio de ReadXml.
pizzaDs.ReadXml(dataDir + "CustomerData.xml");
string fileName = "Invoice Template.doc";

// Abra o documento modelo.
Document doc = new Document(dataDir + fileName);
	 
// Apare os valores de mala direta de espaços em branco à direita e à esquerda.
doc.MailMerge.TrimWhitespaces = false;
	 
// Execute a mala direta aninhada com regiões.
doc.MailMerge.ExecuteWithRegions(pizzaDs);
dataDir = dataDir + RunExamples.GetOutputFilePath(fileName);

// Salve a saída em arquivo.
doc.Save(dataDir);

Debug.Assert(doc.MailMerge.GetFieldNames().Length == 0, "There was a problem with mail merge");
Console.WriteLine("\nMail merge performed with nested data successfully.\nFile saved at " + dataDir);

Documento do Word após a mala direta

Abaixo está a primeira página do documento do Word resultante após a execução da mala direta.

Documento do Word após a mala direta

Conclusão

Aspose.Words for .NET é uma API de mala direta rica em recursos que fornece todos os recursos padrão e estendidos de mala direta para aplicativos .NET. Em poucas linhas de código, você pode criar relatórios simples ou complexos de vários tipos de fontes de dados sem problemas. Você pode ler mais sobre a API .NET Mail Merge na documentação. Para saber mais sobre o Aspose.Words for .NET, comece com os guias do desenvolvedor e os exemplos de código do GitHub.

Experimente o Aspose.Words for .NET gratuitamente

Você pode obter uma licença temporária gratuita para experimentar o Aspose.Words for .NET sem quaisquer limitações. Obtenha sua licença temporária agora.

Veja também