Wednesday, August 20, 2014

SharePoint 2013 - Generate document with data using server object model

When we provide a content management solution with SharePoint, often we need to generate reports or documents using existing data. To generate reports we can use SSRS with “SharePoint List” as the data source. But, how can we generate a word document in a given template?

In this article I will show how to generate a word document with data using SharePoint server object model. To explain the concept I will implement following scenario.

  • Generate contract approval summary document from a template
  • Fill approvers section from list fields

Following are the steps we need to follow.

1. Create a content type and associate with list fields

I’ve created the content type with necessary fields in visual studio and deployed to the farm.

image

2. Associate the content type to a document library and go to advanced settings to change the document template

we will navigate to advanced settings and upload an empty word document (e.g.: template.docx)

image

3. Click on edit template and modify the document to build the template

image

To add dynamic content, we will use quick parts section of the document. As you can see, the content type fields are available in the quick parts section. we will embed those fields to our document accordingly

image

image

Then we will save changes

4. Use following code to create document

  1. var web = SPContext.Current.Web;
  2. web.AllowUnsafeUpdates = true;
  3.  
  4. var tplurl = listItem.ParentList.ContentTypes["Contract Approval Summary"].DocumentTemplateUrl;
  5. byte[] stream = web.GetFile(tplurl).OpenBinary();
  6.  
  7.  
  8. var itemProperties = new Hashtable();
  9. itemProperties.Add("AGMName", agmName);
  10. itemProperties.Add("RegionalControllerName", regionalName);
  11. itemProperties.Add("RVPName", rvpName);
  12.  
  13. listItem.ParentList.RootFolder.Files.Add(listItem.DisplayName + " Approval Summary.docx", stream, itemProperties, true);
  14. web.AllowUnsafeUpdates = false;

That will create the document with required fields.Those fields will be embedded to the document as per the template

Sunday, August 3, 2014

Programmatically add tasks to timeline in SharePoint 2013 Tasks list

In a previous post I described about the new Timeline feature in SharePoint 2013. But tasks are not added to the timeline automatically, which is a huge drawback. As a result we need to create the task and it to the timeline manually as below.

image

From this post I will explain how to add tasks to timeline automatically. There are two options to derive at a solution. They are,

  • Using JavaScripts
  • Using an Event Receiver

In this article I will show a way to implement the task using Item Added event receiver configured to Tasks list type. Following are two logical steps included in the solution.

1. Set required properties in the tasks list

In the RootFolder of a particular Tasks list, there are three properties relevant to the Timeline control. When we create the list, those properties are not automatically set. As a result we have to set those three properties, namely,

  • TimeLineDefaultView
  • TimeLineAllViews
  • TimeLine_TimeLine

2. Get xml document in TimeLine_TimeLine property, and add required nodes

We have to add xml nodes to “tskSet” and “mlSet” sections to represent the task which is to be displayed in Timeline control.

Following is the sample code I used to execute above steps

  1. var web = properties.Web as SPWeb;
  2. var doc = new XmlDocument();
  3. var taskList = web.Lists[properties.ListId];
  4. var root = taskList.RootFolder;
  5.  
  6. if (root.Properties["Timeline_Timeline"] == null)
  7. {
  8. //Add timeline related properties
  9. root.SetProperty("TimelineDefaultView", "Timeline");
  10. root.SetProperty("TimelineAllViews", "Timeline");
  11. //Add default xml to Timeline_Timeline property
  12. root.SetProperty("Timeline_Timeline",@"<TLViewData><fmtSet><fmt id='0' clr='FFEE2222' thm='0001' t1='0' t2='1' type='0' /><fmt id='1' clr='FFEE2222' thm='0001' t1='2' t2='3' type='1' /><fmt id='2' clr='FFEE2222' thm='0001' t1='4' t2='5' type='2' /><fmt id='3' clr='FFEE2222' thm='0001' t1='6' t2='7' type='3' /></fmtSet><fltSet><ft id='{00000000-0000-0000-0000-000000000000}' uid='4294967295' uidSrc='1' onTL='0' fmt='1' y='4294967282' x='0' h='20' /></fltSet><tskSet><t id='{00000000-0000-0000-0000-000000000000}' uid='4294967295' uidSrc='1' onTL='0' fmt='0' ch='4294967295' /></tskSet><options dateFormat='255' panZoomT='9' ProjSummFmt='3' showDates='1' showProjSummDates='0' showToday='1' showTS='1' timelineHeight='133' timelineWidth='-1' timescaleT='8' todayT='10' /><mlSet>
  13. <m id='{00000000-0000-0000-0000-000000000000}' uid='4294967295' uidSrc='1' onTL='0' fmt='2' y='35' x='0' /></mlSet><txtSet><style id='0' type='0' clr='FFEE2222' thm='0001' sz='8' font='Segoe UI' bold='0' ital='0' und='0' strk='0' /><style id='1' type='1' clr='FFEE2222' thm='0001' sz='8' font='Segoe UI' bold='0' ital='0' und='0' strk='0' /><style id='2' type='2' clr='FF999999' thm='0001' sz='8' font='Segoe UI' bold='0' ital='0' und='0' strk='0' /><style id='3' type='3' clr='FFB3B3B3' thm='0001' sz='8' font='Segoe UI Light' bold='0' ital='0' und='0' strk='0' /><style id='4' type='4' clr='FF525051' thm='0001' sz='10' font='Segoe UI' bold='0' ital='0' und='0' strk='0' /><style id='5' type='5' clr='FFB3B3B3' thm='0001' sz='8' font='Segoe UI Light' bold='0' ital='0' und='0' strk='0' /><style id='6' type='6' clr='FF999999' thm='0001' sz='9' font='Segoe UI' bold='0' ital='0' und='0' strk='0' /><style id='7' type='7' clr='FF999999' thm='0001' sz='8' font='Segoe UI' bold='0' ital='0' und='0' strk='0' /><style id='8' type='8' clr='FF999999' thm='0001' sz='8' font='Segoe UI' bold='0' ital='0' und='0' strk='0' /><style id='9' type='9' clr='FFFFA614' thm='0001' sz='8' font='Segoe UI Semibold' bold='1' ital='0' und='0' strk='0' /><style id='10' type='10' clr='FFFFA72B' thm='0001' sz='10' font='Segoe UI Semibold' bold='0' ital='0' und='0' strk='0' /></txtSet></TLViewData>");
  14. root.Update();
  15. }
  16.  
  17. doc.LoadXml(root.Properties["Timeline_Timeline"].ToString());
  18.  
  19. //Create required xml nodes
  20. var tElement = doc.CreateElement("t");
  21. tElement.SetAttribute("id", "{" + properties.ListItemUniqueId.ToString() + "}");
  22. tElement.SetAttribute("uid", properties.ListItemId.ToString());
  23. tElement.SetAttribute("uidSrc", "1");
  24. tElement.SetAttribute("onTL", "1");
  25. tElement.SetAttribute("fmt", "0");
  26. tElement.SetAttribute("ch", "4294967295");
  27.  
  28. var mElement = doc.CreateElement("m");
  29. mElement.SetAttribute("id", "{" + properties.ListItemUniqueId.ToString() + "}");
  30. mElement.SetAttribute("uid", properties.ListItemId.ToString());
  31. mElement.SetAttribute("uidSrc", "1");
  32. mElement.SetAttribute("onTL", "1");
  33. mElement.SetAttribute("fmt", "2");
  34. mElement.SetAttribute("y", "35");
  35. mElement.SetAttribute("x", "0");
  36.  
  37. //Add created nodes to xml document
  38. doc.SelectNodes("/TLViewData/tskSet/t")[doc.SelectNodes("/TLViewData/tskSet/t").Count - 1].AppendChild(tElement);
  39. doc.SelectNodes("/TLViewData/mlSet/m")[doc.SelectNodes("/TLViewData/mlSet/m").Count - 1].AppendChild(mElement);
  40. root.SetProperty("Timeline_Timeline", doc.OuterXml);
  41. root.Update();
  42.  
  43. base.ItemAdded(properties);

After deploying the solution, tasks are added to the timeline automatically.