Automatizar documentos Office 2010 con datos de SharePoint 2010

Como Office 2010 y SharePoint 2010 ya están al caer, me apetecía crear una aplicación que nos permita trabajar con ambas plataformas, y que por supuesto tenga alguna utilidad interesante. En el artículo de hoy vamos a ver como podemos automatizar nuestros documentos de Word 2010 con los datos que obtenemos de una lista de contactos de SharePoint 2010. Esto es muy útil para informes que siguen una misma estructura como puede ser la invitación a un evento, que es el caso que vamos a ver a continuación.

Para ello, partiendo de un documento inteligente (Smart Document), vamos a utilizar la potencia que nos ofrecen las herramientas VSTO (Visual Studio Tools for Office) para la creación de aplicaciones de negocio para Office. Estas ya vienen integradas en VS 2010, y nos permiten crear aplicaciones tanto para la versión 2007 como para la versión 2010 de Office.

Abrimos VS 2010 y creamos un proyecto de tipo Word Document2010, que en nuestro caso llamaremos InvitacionCES.

image 

Una vez creado el documento sobre el que vamos a trabajar, lo primero que hacemos es añadir un elemento de tipo Action Pane Control, que utilizaremos como navegador de nuestros contactos. Para ello hacemos clic con el botón derecho sobre nuestro proyecto y seleccionamos Add > New Item> ActionsPaneControl que llamaremos NavegadorContactos.

image 

Dentro de nuestro panel de acciones, añadiremos los controles que vamos a utilizar para mostrar las propiedades de los elementos de la lista, teniendo en cuenta cuales son las propiedades que queremos mostrar. Viendo los elementos que debemos rellenar en nuestro documento, nuestro panel de acciones debe tener un aspecto similar a este:

image

Hasta este punto hemos diseñado nuestro panel de acciones, pero todavía nos falta añadirlo al documento Word para que este se visualice, y darle la funcionalidad deseada. Para lo primero, es necesario crear una instancia del control en el archivo ThisDocument.cs de nuestra aplicación:

  1. NavegadorContactos Contactos = new NavegadorContactos();

Y hacer que dicho control se añada a la aplicación cuando arrancamos Word. Esto último se hace a través del evento ThisDocument_Startup

  1. private void ThisDocument_Startup(object sender, System.EventArgs e)
  2.         {
  3.             this.ActionsPane.Controls.Add(Contactos);
  4.         }

A continuación vamos a darle funcionalidad al “navegador de contactos”. En nuestro caso, vamos a implementar un servicio web que nos permita conectar la aplicación cliente de Office con nuestro sitio SharePoint: http://sharepoint2010:200 y que rellene los controles de nuestro panel con los datos de la lista de contactos. Para añadir un servicio web a la misma, pinchamos con el botón derecho sobre Referencias > Agregar referencia de servicio en el explorador de soluciones. Dentro de todos los servicios disponibles en la máquina local, especificamos la URL del servicio al que nos queremos conectar, que en nuestro caso es http://localhost:200/_vti_bin/Lists.asmx (ya que Contactos es un tipo de Lista), y le damos el nombre de ContactosSP. De esta manera ya podemos usar este servicio Web en nuestro proyecto.

image 

Ahora que ya hemos creado nuestro servicio web para conectarnos a la aplicación SharePoint, vamos a implementar el código necesario para que los controles realicen su función correctamente.  Para ello vamos al archivo NavegadorContactos.cs, y añadimos dos clases más aparte de la existente (NavegadorContactos) una que se encargará de construir los Items que forman nuestro ComboBox:

Elementos del combobox
  1. public class Item
  2.     {
  3.         public string Name;
  4.  
  5.         public Item(string name)
  6.         {
  7.             Name = name;
  8.  
  9.         }
  10.         public override string ToString()
  11.         {
  12.             // Genera el texto mostrado en el ComboBox
  13.             return Name;
  14.         }
  15.     }

Y otra que se encargará de construir un objeto Contacto con los siguientes atributos:

 

 

Elemento Contacto
  1. public class Contacto
  2.     {
  3.         public string Name;
  4.         public string LastName;
  5.         public string City;
  6.         public string ZipCode;
  7.         public string Country;
  8.         public string Email;
  9.         public string Telephone;
  10.         public string Company;
  11.  
  12.         public Contacto(string name, string lastname, string city, string zipcode, string country, string email, string telephone, string company)
  13.         {
  14.             Name = name;
  15.             LastName = lastname;
  16.             City = city;
  17.             ZipCode = zipcode;
  18.             Country = country;
  19.             Email = email;
  20.             Telephone = telephone;
  21.             Company = company;
  22.         }
  23.  
  24.     }

 

A continuación dentro de la clase NavegadorContactos, inicializamos las variables que vamos a utilizar y que son necesarias para ir leyendo las propiedad de los elementos de la lista en SharePoint, ya que dicha información la obtenemos a partir de un documento XML

 

Inicializacion variables
  1. XmlNode listNode, contactFN, contactLN, contactEM, contactMP, contactWC, contactZC, contactCR, contactCN;
  2.         XmlAttributeCollection nodeAttribs;
  3.         XmlDocument xmlDoc;
  4.         XmlNode ndViewFields;
  5.         XmlNode ndListItems;
  6.         Contacto cont;
  7.         List<Contacto> mContact = new List<Contacto>();

Creamos un método llamado BuscarContactos que es el que se encargará de conectarse al servicio web creado y obtener los datos almacenados en nuestra lista de Contactos. Constará del siguiente código:

Buscar Contactos
  1. public void BuscarContactos()
  2.         {
  3.  
  4.             ContactosSP.Lists contactosService = new InvitacionCES.ContactosSP.Lists();
  5.  
  6.             // Creamos las credenciales que nos permiten conectarnos a
  7.             // SharePoint y las asignamos al servicio
  8.  
  9.             System.Net.NetworkCredential myCred = new System.Net.NetworkCredential(«Administrador», «AdmSP2010»);
  10.  
  11.             contactosService.Credentials = myCred;
  12.  
  13.             // Recuperamos
  14.  
  15.             listNode = contactosService.GetList(«Contactos»);
  16.  
  17.             // Creamos las estructuras XML necesarias para volcar nuestra información
  18.  
  19.             xmlDoc = new System.Xml.XmlDocument();
  20.  
  21.             ndViewFields = xmlDoc.CreateNode(XmlNodeType.Element, «ViewFields», «»);
  22.  
  23.  
  24.             // Indicamos los campos que queremos que nos muestre, es decir la vista
  25.  
  26.             ndViewFields.InnerXml = «<FieldRef Name=’LinkTitle’/><FieldRef Name=’FirstName’/><FieldRef Name=’Email’/><FieldRef Name=’CellPhone’/><FieldRef Name=’WorkCity’/><FieldRef Name=’WorkZip’/><FieldRef Name=’Company’/><FieldRef Name=’WorkCountry’/>»;
  27.  
  28.  
  29.             try
  30.             {
  31.                 // Indicamos que lista queremos que lea y la vista de la misma
  32.  
  33.                 ndListItems = contactosService.GetListItems(«Contactos», null, null, ndViewFields, null, null, null);
  34.  
  35.                 // Procesamos cada elemento recuperado buscando el título
  36.  
  37.                 foreach (XmlNode node in ndListItems.ChildNodes)
  38.                 {
  39.  
  40.                     // El contenido va en los subnodos que nos devuelve SharePoint
  41.  
  42.                     foreach (XmlNode subnode in node.ChildNodes)
  43.                     {
  44.  
  45.                         // Buscamos valores de los atributos del nodo
  46.  
  47.                         nodeAttribs = subnode.Attributes;
  48.  
  49.                         if (nodeAttribs != null)
  50.                         {
  51.                             // Obtenemos los valores de los atributos de los subnodos
  52.                             contactFN = nodeAttribs.GetNamedItem(«ows_FirstName»);
  53.                             contactLN = nodeAttribs.GetNamedItem(«ows_LinkTitle»);
  54.                             contactEM = nodeAttribs.GetNamedItem(«ows_Email»);
  55.                             contactMP = nodeAttribs.GetNamedItem(«ows_CellPhone»);
  56.                             contactWC = nodeAttribs.GetNamedItem(«ows_WorkCity»);
  57.                             contactZC = nodeAttribs.GetNamedItem(«ows_WorkZip»);
  58.                             contactCR = nodeAttribs.GetNamedItem(«ows_WorkCountry»);
  59.                             contactCN = nodeAttribs.GetNamedItem(«ows_Company»);
  60.                             //Creamos nuestros contactos y los añadimos a la lista de contactos
  61.                             cont = new Contacto(contactFN.Value, contactLN.Value, contactWC.Value, contactZC.Value, contactCR.Value, contactEM.Value, contactMP.Value, contactCN.Value);
  62.                             mContact.Add(cont);
  63.                             //Anadimos los apellidos de nuestros contactos al comboBox
  64.                             cb_Contactos.Items.Add(new Item(cont.LastName));
  65.  
  66.                         }
  67.  
  68.  
  69.                     };
  70.  
  71.                 };
  72.  
  73.             }
  74.             // Definimos una excepción de conexión al servicio web
  75.  
  76.             catch (System.Web.Services.Protocols.SoapException ex)
  77.             {
  78.  
  79.                 MessageBox.Show(«Message:n» + ex.Message + «nDetail:n» + ex.Detail.InnerText + «nStackTrace:n» + ex.StackTrace);
  80.  
  81.             }
  82.  
  83.         }

Llamaremos a dicho método cuando se haga clic sobre el botón Conectar. Mediante este método se van a cargar en nuestro ComboBox los apellidos de los distintos contactos que tengamos almacenados en nuestra lista de Contactos.

Conectar
  1. private void but_Conectar_Click(object sender, EventArgs e)
  2.         {
  3.             BuscarContactos();
  4.             //Deja no visible el control conectar
  5.             but_Conectar.Visible = false;
  6.         }

Y por último definimos el evento, que hará que al seleccionar en cada uno de elementos del combobox se nos carguen el resto de valores de nuestro contacto (nombre, email, teléfono…) tanto en los controles del navegador como en los controles del documento.

 

Carga de contactos
  1. private void cb_Contactos_SelectedIndexChanged(object sender, EventArgs e)
  2.         {
  3.             for (int i = 0; i <= cb_Contactos.SelectedIndex; i++)
  4.             {
  5.                 Globals.ThisDocument.richTextContentControl1.Text = mContact[i].LastName;
  6.  
  7.                 tb_Email.Text = mContact[i].Email;//Rellenamos el cuadro de texto Email del navegador
  8.                 Globals.ThisDocument.richTextContentControl2.Text = tb_Email.Text;//Rellenamos el campo Email del documento
  9.  
  10.                 tb_City.Text = mContact[i].City;//Rellenamos el cuadro de texto Ciudad del navegador
  11.                 Globals.ThisDocument.richTextContentControl3.Text = tb_City.Text;//Rellenamos el campo Ciudad del documento
  12.  
  13.                 tb_ZipCode.Text = mContact[i].ZipCode;//Rellenamos el cuadro de texto Codigo Postal del navegador
  14.                 Globals.ThisDocument.richTextContentControl4.Text = tb_ZipCode.Text;//Rellenamos el Codigo Postal del documento
  15.  
  16.                 tb_Country.Text = mContact[i].Country;//Rellenamos el cuadro de texto Pais del navegador
  17.                 Globals.ThisDocument.richTextContentControl6.Text = tb_Country.Text;//Rellenamos el campo Pais del documento
  18.  
  19.                 tb_Telephone.Text = mContact[i].Telephone;//Rellenamos el cuadro de texto Telefono del navegador
  20.                 Globals.ThisDocument.richTextContentControl5.Text = tb_Telephone.Text;//Rellenamos el campo Telefono del documento
  21.  
  22.                 tb_Company.Text = mContact[i].Company;
  23.                 Globals.ThisDocument.richTextContentControl7.Text = tb_Company.Text;
  24.  
  25.                 tb_Name.Text = mContact[i].Name; //Rellenamos el cuadro de texto Nombre del navegador
  26.                 Globals.ThisDocument.richTextContentControl8.Text = tb_Name.Text;//Rellenamos el campo Nombre del documento
  27.             }
  28.  
  29.  
  30.         }

Para ver que todo funciona correctamente, compilamos (F5) y observamos que el resultado es el siguiente:

image

Como se puede ver, es posible navegar por los distintos elementos mediante el combobox, de forma que podemos rellenar nuestros documentos de forma automática y sin el menor esfuerzo….para el usuario.

Además si probamos a añadir más contactos en nuestra lista de SharePoint veremos como estos se actualizan dinámicamente al conectarnos al servicio web desde nuestro navegador de contactos.

Espero que os resulte interesante.

Descargar el proyecto aquí

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *