Cómo acceder a objetos de interoperabilidad de Office

C# tiene nuevas características que simplifican el acceso a objetos de la API de Office. Las nuevas características incluyen argumentos con nombre y opcionales, un nuevo tipo llamado dynamic y la capacidad de pasar argumentos a parámetros de referencia en los métodos COM como si fueran parámetros de valor.

En este artículo se utilizarán las nuevas características para escribir código que crea y muestra una hoja de cálculo de Microsoft Office Excel. Se escribe código para agregar un documento de Office Word que contiene un icono que está vinculado a la hoja de cálculo de Excel.

Para completar este tutorial, es necesario tener Microsoft Office Excel 2007 y Microsoft Office Word 2007 —o una versión posterior— instalados en el equipo.

Nota:

Es posible que tu equipo muestre nombres o ubicaciones diferentes para algunos de los elementos de la interfaz de usuario de Visual Studio en las siguientes instrucciones. La edición de Visual Studio que se tenga y la configuración que se utilice determinan estos elementos. Para obtener más información, vea Personalizar el IDE.

Importante

VSTO (Visual Studio Tools para Office) se basa en .NET Framework. Los complementos COM también se pueden escribir con .NET Framework. No se pueden crear complementos de Office con .NET Core y .NET 5 o versiones posteriores, las últimas versiones de .NET. Esto se debe a que .NET Core/.NET 5 o versiones posteriores no pueden funcionar junto con .NET Framework en el mismo proceso, y se pueden provocar errores de carga de complementos. Puede seguir usando .NET Framework a fin de escribir complementos VSTO y COM para Office. Microsoft no actualizará VSTO ni la plataforma de complementos COM para usar .NET Core, o .NET 5 o versiones posteriores. Puede utilizar .NET Core y .NET 5 o versiones posteriores, incluido ASP.NET Core, para crear el lado servidor de complementos web de Office.

Para crear una aplicación de consola nueva

  1. Inicie Visual Studio.
  2. En el menú Archivo , seleccione Nuevoy haga clic en Proyecto. Aparecerá el cuadro de diálogo Nuevo proyecto .
  3. En el panel Plantillas instaladas, expanda C# y, a continuación, seleccione Windows.
  4. En la parte superior del cuadro de diálogo Nuevo proyecto, asegúrese de seleccionar .NET Framework 4 (o una versión posterior) como plataforma de destino.
  5. En el panel Plantillas, seleccione Aplicación de consola.
  6. Escriba un nombre para el proyecto en el campo Nombre.
  7. Seleccione Aceptar.

El proyecto nuevo aparece en el Explorador de soluciones.

Para agregar referencias

  1. En el Explorador de soluciones, haga clic con el botón derecho en el nombre del proyecto y luego seleccione Agregar referencia. Aparecerá el cuadro de diálogo Agregar referencia.
  2. En la página de Ensamblados, seleccione Microsoft.Office.Interop.Word en la lista Nombre de componente y, después, mantenga presionada la tecla CTRL y seleccione Microsoft.Office.Interop.Excel. Si no ve los ensamblados, es posible que tenga que instalarlos. Vea Cómo: Instalación de ensamblados de interoperabilidad primarios de Office.
  3. Seleccione Aceptar.

Para agregar las directivas using necesarias

En el Explorador de soluciones, haga clic con el botón derecho en el archivo Program.cs y luego seleccione Ver código. Agregue las directivas using siguientes a la parte superior del archivo de código:

using Excel = Microsoft.Office.Interop.Excel;
using Word = Microsoft.Office.Interop.Word;

Para crear una lista de las cuentas bancarias

Pegue la definición de clase siguiente en Program.cs, bajo la clase Program.

public class Account
{
    public int ID { get; set; }
    public double Balance { get; set; }
}

Agregue el código siguiente al método Main para crear una lista bankAccounts lista que contenga dos cuentas.

// Create a list of accounts.
var bankAccounts = new List<Account> {
    new Account {
                  ID = 345678,
                  Balance = 541.27
                },
    new Account {
                  ID = 1230221,
                  Balance = -127.44
                }
};

Para declarar un método que exporta información de cuentas a Excel

  1. Agregue el método siguiente a la clase Program para configurar una hoja de cálculo de Excel. El método Add tiene un parámetro opcional para especificar una plantilla determinada. Los parámetros opcionales permiten omitir el argumento para ese parámetro si se desea utilizar el valor predeterminado del parámetro. Dado que no ha proporcionado ningún argumento, Add usa la plantilla predeterminada y crea un libro. La instrucción equivalente en versiones anteriores de C# requiere un argumento de marcador de posición: ExcelApp.Workbooks.Add(Type.Missing).
static void DisplayInExcel(IEnumerable<Account> accounts)
{
    var excelApp = new Excel.Application();
    // Make the object visible.
    excelApp.Visible = true;

    // Create a new, empty workbook and add it to the collection returned
    // by property Workbooks. The new workbook becomes the active workbook.
    // Add has an optional parameter for specifying a particular template.
    // Because no argument is sent in this example, Add creates a new workbook.
    excelApp.Workbooks.Add();

    // This example uses a single workSheet. The explicit type casting is
    // removed in a later procedure.
    Excel._Worksheet workSheet = (Excel.Worksheet)excelApp.ActiveSheet;
}

Agregue el siguiente código al final de DisplayInExcel. El código inserta valores en las dos primeras columnas de la primera fila de la hoja de cálculo.

// Establish column headings in cells A1 and B1.
workSheet.Cells[1, "A"] = "ID Number";
workSheet.Cells[1, "B"] = "Current Balance";

Agregue el siguiente código al final de DisplayInExcel. El bucle foreach coloca la información de la lista de cuentas en las dos primeras columnas de filas sucesivas de la hoja de cálculo.


var row = 1;
foreach (var acct in accounts)
{
    row++;
    workSheet.Cells[row, "A"] = acct.ID;
    workSheet.Cells[row, "B"] = acct.Balance;
}

Agregue el código siguiente al final de DisplayInExcel para ajustar los anchos de columna a fin de adaptarlos al contenido.

workSheet.Columns[1].AutoFit();
workSheet.Columns[2].AutoFit();

Las versiones anteriores de C# requieren una conversión explícita para estas operaciones, ya que ExcelApp.Columns[1] devuelve Object y AutoFit es un método Range de Excel. Las siguientes líneas muestran la conversión.

((Excel.Range)workSheet.Columns[1]).AutoFit();
((Excel.Range)workSheet.Columns[2]).AutoFit();

En C#, el valor devuelto Object se convierte automáticamente en dynamic si se hace referencia al ensamblado mediante la opción del compilador EmbedInteropTypes o, de forma equivalente, si la propiedad Incrustar tipos de interoperabilidad de Excel es true. El valor predeterminado de esta propiedad es true.

Para ejecutar el proyecto

Agregue la línea siguiente al final de Main.

// Display the list in an Excel spreadsheet.
DisplayInExcel(bankAccounts);

Presione CTRL+F5. Aparece una hoja de cálculo de Excel que contiene los datos de las dos cuentas.

Para agregar un documento de Word

El código siguiente abre una aplicación de Word y crea un icono que se vincula a la hoja de cálculo de Excel. Pegue el método CreateIconInWordDoc, proporcionado más adelante en este paso, en la clase Program. CreateIconInWordDoc usa argumentos con nombre y opcionales para reducir la complejidad de las llamadas de método a Add y PasteSpecial. Estas llamadas incorporan otras dos características que simplifican las llamadas a métodos COM que tienen parámetros de referencia. En primer lugar, puede enviar argumentos a los parámetros de referencia como si fueran parámetros de valor. Es decir, puede enviar valores directamente, sin necesidad de crear una variable para cada parámetro de referencia. El compilador genera variables temporales para contener los valores de argumento y las descarta cuando se regresa de la llamada. En segundo lugar, se puede omitir la palabra clave ref en la lista de argumentos.

El método Add tiene cuatro parámetros de referencia, todos ellos opcionales. Puede omitir los argumentos de cualquiera o de todos los parámetros si desea usar sus valores predeterminados.

El método PasteSpecial inserta el contenido del Portapapeles. El método tiene siete parámetros de referencia, todos ellos opcionales. El siguiente código especifica los argumentos para dos de ellos: Link, para crear un vínculo con el origen del contenido del Portapapeles, y DisplayAsIcon, para mostrar el vínculo como un icono. Puede usar argumentos con nombre para esos dos argumentos y omitir los demás. Aunque estos argumentos son parámetros de referencia, no es necesario utilizar la palabra clave ref ni crear variables para enviarlas como argumentos. Puede enviar los valores directamente.

static void CreateIconInWordDoc()
{
    var wordApp = new Word.Application();
    wordApp.Visible = true;

    // The Add method has four reference parameters, all of which are
    // optional. Visual C# allows you to omit arguments for them if
    // the default values are what you want.
    wordApp.Documents.Add();

    // PasteSpecial has seven reference parameters, all of which are
    // optional. This example uses named arguments to specify values
    // for two of the parameters. Although these are reference
    // parameters, you do not need to use the ref keyword, or to create
    // variables to send in as arguments. You can send the values directly.
    wordApp.Selection.PasteSpecial( Link: true, DisplayAsIcon: true);
}

Agregue la siguiente instrucción al final de Main.

// Create a Word document that contains an icon that links to
// the spreadsheet.
CreateIconInWordDoc();

Agregue la siguiente instrucción al final de DisplayInExcel. El método Copy agrega la hoja de cálculo en el Portapapeles.

// Put the spreadsheet contents on the clipboard. The Copy method has one
// optional parameter for specifying a destination. Because no argument
// is sent, the destination is the Clipboard.
workSheet.Range["A1:B3"].Copy();

Presione CTRL+F5. Un documento de Word aparecerá con un icono. Haga doble clic en el icono para abrir la hoja de cálculo en primer plano.

Para establecer la propiedad Incrustar tipos de interoperabilidad

Es posible realizar más mejoras si se llama a un tipo COM que no requiere un ensamblado de interoperabilidad primario (PIA) en tiempo de ejecución. Si se elimina la dependencia de PIA, la versión gana en independencia y se facilita la implementación. Para obtener más información sobre las ventajas de la programación sin PIA, consulte Tutorial: Insertar los tipos de los ensamblados administrados.

Además, la programación es más fácil porque el tipo dynamic representa los tipos requeridos y devueltos que se declaran en los métodos COM. Las variables de tipo dynamic no se evalúan hasta el tiempo de ejecución, lo que elimina la necesidad de la conversión explícita. Para obtener más información, vea Uso del tipo dynamic.

El comportamiento predeterminado es insertar información de tipos en lugar de utilizar los ensamblados de interoperabilidad primarios. Debido a ese comportamiento predeterminado, algunos de los ejemplos anteriores se simplifican. No necesita ninguna conversión explícita. Por ejemplo, la declaración de worksheet en DisplayInExcel se escribe como Excel._Worksheet workSheet = excelApp.ActiveSheet en lugar de Excel._Worksheet workSheet = (Excel.Worksheet)excelApp.ActiveSheet. Las llamadas a AutoFit en el mismo método también requerirían conversión explícita sin el valor predeterminado, porque ExcelApp.Columns[1] devuelve Object y AutoFit es un método de Excel. En el código siguiente se muestra la conversión.

((Excel.Range)workSheet.Columns[1]).AutoFit();
((Excel.Range)workSheet.Columns[2]).AutoFit();

Para cambiar el valor predeterminado y usar los ensamblados de interoperabilidad primarios en lugar de incrustar información de tipos, expanda el nodo Referencias del Explorador de soluciones y, después, seleccione Microsoft.Office.Interop.Excel o Microsoft.Office.Interop.Word. Si no ve la ventana Propiedades, presione F4. Busque Incrustar tipos de interoperabilidad en la lista de propiedades y cambie su valor a False. Del mismo modo, se puede compilar mediante la opción del compilador References en lugar de EmbedInteropTypes en un símbolo del sistema.

Para agregar formato adicional a la tabla

Reemplace las dos llamadas a AutoFit en DisplayInExcel con la siguiente instrucción.

// Call to AutoFormat in Visual C# 2010.
workSheet.Range["A1", "B3"].AutoFormat(
    Excel.XlRangeAutoFormat.xlRangeAutoFormatClassic2);

El método AutoFormat tiene siete parámetros de valor, todos ellos opcionales. Los argumentos con nombre y los argumentos opcionales permiten proporcionar argumentos para ninguno, algunos o todos ellos. En la instrucción anterior, se proporciona un argumento para uno solo de los parámetros, Format. Puesto que Format es el primer parámetro de la lista correspondiente, no es necesario proporcionar el nombre de parámetro. Sin embargo, la instrucción puede ser más fácil de entender si se incluye el nombre del parámetro, como se muestra en el código siguiente.

// Call to AutoFormat in Visual C# 2010.
workSheet.Range["A1", "B3"].AutoFormat(Format:
    Excel.XlRangeAutoFormat.xlRangeAutoFormatClassic2);

Presione CTRL+F5 para ver el resultado. Puede encontrar otros formatos incluidos en la enumeración XlRangeAutoFormat.

Ejemplo

En el código siguiente se muestra el ejemplo completo.

using System.Collections.Generic;
using Excel = Microsoft.Office.Interop.Excel;
using Word = Microsoft.Office.Interop.Word;

namespace OfficeProgrammingWalkthruComplete
{
    class Walkthrough
    {
        static void Main(string[] args)
        {
            // Create a list of accounts.
            var bankAccounts = new List<Account>
            {
                new Account {
                              ID = 345678,
                              Balance = 541.27
                            },
                new Account {
                              ID = 1230221,
                              Balance = -127.44
                            }
            };

            // Display the list in an Excel spreadsheet.
            DisplayInExcel(bankAccounts);

            // Create a Word document that contains an icon that links to
            // the spreadsheet.
            CreateIconInWordDoc();
        }

        static void DisplayInExcel(IEnumerable<Account> accounts)
        {
            var excelApp = new Excel.Application();
            // Make the object visible.
            excelApp.Visible = true;

            // Create a new, empty workbook and add it to the collection returned
            // by property Workbooks. The new workbook becomes the active workbook.
            // Add has an optional parameter for specifying a particular template.
            // Because no argument is sent in this example, Add creates a new workbook.
            excelApp.Workbooks.Add();

            // This example uses a single workSheet.
            Excel._Worksheet workSheet = excelApp.ActiveSheet;

            // Earlier versions of C# require explicit casting.
            //Excel._Worksheet workSheet = (Excel.Worksheet)excelApp.ActiveSheet;

            // Establish column headings in cells A1 and B1.
            workSheet.Cells[1, "A"] = "ID Number";
            workSheet.Cells[1, "B"] = "Current Balance";

            var row = 1;
            foreach (var acct in accounts)
            {
                row++;
                workSheet.Cells[row, "A"] = acct.ID;
                workSheet.Cells[row, "B"] = acct.Balance;
            }

            workSheet.Columns[1].AutoFit();
            workSheet.Columns[2].AutoFit();

            // Call to AutoFormat in Visual C#. This statement replaces the
            // two calls to AutoFit.
            workSheet.Range["A1", "B3"].AutoFormat(
                Excel.XlRangeAutoFormat.xlRangeAutoFormatClassic2);

            // Put the spreadsheet contents on the clipboard. The Copy method has one
            // optional parameter for specifying a destination. Because no argument
            // is sent, the destination is the Clipboard.
            workSheet.Range["A1:B3"].Copy();
        }

        static void CreateIconInWordDoc()
        {
            var wordApp = new Word.Application();
            wordApp.Visible = true;

            // The Add method has four reference parameters, all of which are
            // optional. Visual C# allows you to omit arguments for them if
            // the default values are what you want.
            wordApp.Documents.Add();

            // PasteSpecial has seven reference parameters, all of which are
            // optional. This example uses named arguments to specify values
            // for two of the parameters. Although these are reference
            // parameters, you do not need to use the ref keyword, or to create
            // variables to send in as arguments. You can send the values directly.
            wordApp.Selection.PasteSpecial(Link: true, DisplayAsIcon: true);
        }
    }

    public class Account
    {
        public int ID { get; set; }
        public double Balance { get; set; }
    }
}

Consulte también