programming4us
         
 
 
Sharepoint

SharePoint 2010 : Word Automation Services - Demonstration Scenario (part 3) - Combine Documents Using OpenXML, Converting an OpenXML Document to an Alternative Format

- How To Install Windows Server 2012 On VirtualBox
- How To Bypass Torrent Connection Blocking By Your ISP
- How To Install Actual Facebook App On Kindle Fire
7/15/2013 9:36:01 PM

3. Creating a Custom Job Definition

With our user interface largely complete, our next step is to define a custom job that will compile all documents in our document set and send the compiled output to Word Automation Services for conversion to PDF.

In Visual Studio, add a new class named DocumentCombinerJob.cs. Add the following code to the file:

public class DocumentCombinerJob : SPJobDefinition
{
  [Persisted]
  private Guid _siteId;
  [Persisted]
  private Guid _webId;
  [Persisted]
  private Guid _folderId;
  [Persisted]
  private Guid _proxyId;

  public DocumentCombinerJob()
    : base()
  {
  }

  public DocumentCombinerJob(SPListItem documentSet)
    : base("Combine Documents" + Guid.NewGuid().ToString(),
                 SPFarm.Local.TimerService, null, SPJobLockType.None)
  {
    _siteId = documentSet.Web.Site.ID;
    _webId = documentSet.Web.ID;
    _folderId = documentSet.Folder.UniqueId;
    _proxyId = SPServiceContext.Current.GetDefaultProxy(
                             typeof(WordServiceApplicationProxy)).Id;
    Title = "Combine Documents - " + documentSet.Folder.Url;
  }

  protected override bool HasAdditionalUpdateAccess()
  {
    return true;
  }
}


					  

Developers familiar with SharePoint 2007 should notice a few interesting elements in this code snippet. First, check out the HasAdditionalUpdateAccess override. In previous versions of SharePoint, only farm administrators could create jobs. This greatly restricted their usefulness for offloading ad hoc tasks. With SharePoint 2010, where the HasAdditionalUpdateAccess method returns true, any user can create a job.

Also notice that when we’re creating a job, the job can be associated with either a service or an application pool. These associations are primarily for administrative purposes since most jobs run via the SPTimerV4 service. In our example, we’re associating our custom job with the TimerService.

The final thing to notice is that job definitions are serialized when a job is created. As a result, not all types of objects can be defined as properties. For example, the SPListItem isn’t serializable and therefore can’t be stored as a property. To get around this problem, we’re storing a number of identifiers that can be used to recover a reference to the appropriate SPListItem object when the job is deserialized.

4. Combine Documents Using OpenXML

Before we can make use of OpenXML, we need to add a reference to the OpenXML SDK binaries:

  1. Download and install the OpenXML SDK; then, in Visual Studio, add a reference to the DocumentFormat.OpenXML assembly.

  2. Add a reference to the WindowsBase assembly.

  3. To prevent any confusion between similarly named objects within the OpenXML SDK, add the following Using statement to the DocumentCombinerJob.cs file:

    using Word = DocumentFormat.OpenXml.Wordprocessing;
    
  4. In the DocumentCombinerJob.cs file, add the following code:

    public override void Execute(Guid targetInstanceId)
        {
          using (SPSite site = new SPSite(_siteId))
          {
            using (SPWeb web = site.OpenWeb(_webId))
            {
              SPFolder folder = web.GetFolder(_folderId);
    
              SPListItem documentSet = folder.Item;
    
              SPFile output = CombineDocuments(web, folder, documentSet);
    
              ConvertOutput(site, web, output);
            }
          }
        }
    
        private SPFile CombineDocuments(SPWeb web, SPFolder folder,
                                        SPListItem documentSet)
        {
          char[] splitter = { '/' };
          string[] folderName = folder.Name.Split(splitter);
          string templateUrl = documentSet.GetFormattedValue("TemplateUrl1");
          SPFile template = web.GetFile(templateUrl);
          byte[] byteArray = template.OpenBinary();
          using (MemoryStream mem = new MemoryStream())
          {
            mem.Write(byteArray, 0, (int)byteArray.Length);
            using (WordprocessingDocument myDoc =
                                     WordprocessingDocument.Open(mem, true))
            {
              MainDocumentPart mainPart = myDoc.MainDocumentPart;
              foreach (Word.SdtElement sdt in
                 mainPart.Document.Descendants<Word.SdtElement>().ToList())
              {
                Word.SdtAlias alias =
                          sdt.Descendants<Word.SdtAlias>().FirstOrDefault();
                if (alias != null)
                {
                  string sdtTitle = alias.Val.Value;
                  if (sdtTitle == "MergePlaceholder")
                  {
                    foreach (SPFile docFile in folder.Files)
                    {
                      if (docFile.Name.EndsWith(".docx"))
                      {
                        if (docFile.Name != "temp.docx")
                        {
                          InsertDocument(mainPart, sdt, docFile);
                          Word.PageBreakBefore pb = new Word.PageBreakBefore();
                          sdt.Parent.InsertAfter(pb, sdt);
                        }
                      }
                    }
                    sdt.Remove();
                  }
                }
              }
            }
            SPFile temp = folder.Files.Add("temp.docx", mem, true);
            return temp;
          }
        }
    
        protected int id = 1;
    
        void InsertDocument(MainDocumentPart mainPart, Word.SdtElement sdt,
                            SPFile filename)
        {
          string altChunkId = "AIFId" + id;
          id++;
          byte[] byteArray = filename.OpenBinary();
    
      AlternativeFormatImportPart chunk = mainPart.AddAlternativeFormatImportPart(
    AlternativeFormatImportPartType.WordprocessingML, altChunkId);
          using (MemoryStream mem = new MemoryStream())
          {
            mem.Write(byteArray, 0, (int)byteArray.Length);
            mem.Seek(0, SeekOrigin.Begin);
            chunk.FeedData(mem);
          }
          Word.AltChunk altChunk = new Word.AltChunk();
          altChunk.Id = altChunkId;
          OpenXmlElement parent = sdt.Parent.Parent;
          parent.InsertAfter(altChunk, sdt.Parent);
        }
    
        private void ConvertOutput(SPSite site, SPWeb web, SPFile output)
        {
          throw new NotImplementedException();
        }
    
    
    					  

In this code snippet, the CombineDocuments method loads a Microsoft Word format template. The code then searches for all content controls within the document, and where the content control has a title of MergePlaceholder, the contents of all files with a .docx extension within the document set are merged into the template. The merge process makes use of the AlternativeFormatImportPart control to merge contents. This control inserts a binary copy of data into the template at a specific position. When the completed document is rendered in a client application, the merge is performed dynamically each time the document is opened.

5. Converting an OpenXML Document to an Alternative Format

Before we can make use of Word Automation Services in our application, we need to add a reference to the appropriate assembly:

  1. In Visual Studio, add a reference to Microsoft.Office.Word.Server.dll. At the time of writing, this appears in the Add Reference dialog as one of two components named Microsoft Office 2010 component; this problem may be resolved in the final release.

  2. Update the ConvertOutput method in DocumentTimerJob.cs as follows:

    private void ConvertOutput(SPSite site, SPWeb web, SPFile output)
    {
      ConversionJob convJob = new ConversionJob(_proxyId);
      convJob.Name = "Document Assembly";
      convJob.UserToken = web.CurrentUser.UserToken;
      convJob.Settings.UpdateFields = true;
      convJob.Settings.OutputFormat = SaveFormat.PDF;
      convJob.Settings.OutputSaveBehavior = SaveBehavior.AlwaysOverwrite;
      string webUrl = web.Url + "/";
      convJob.AddFile(webUrl + output.Url, webUrl + output.Url.Replace(".docx", ".pdf"));
      convJob.Start();
      Guid jobId = convJob.JobId;
      ConversionJobStatus status = new ConversionJobStatus(_proxyId, jobId, null);
      while (status.Count != (status.Succeeded + status.Failed))
      {
        Thread.Sleep(3000);
        status.Refresh();
      }
      if (status.Failed == status.Count)
      {
        throw new InvalidOperationException();
      }
    
    
    					  

    With our custom job definition completed, we can change the implementation in our user interface to create a new instance of the job.

  3. In SalesProposalWebPartUserControl.ascx.cs, change the StartCompilation_Click method as follows:

    protected void StartCompilation_Click(object sender, EventArgs e)
      {
        SPListItem current = SPContext.Current.ListItem;
    
        current["JobId"] = string.Empty;
        current.Update();
    
        DocumentCombinerJob job = new DocumentCombinerJob(current);
    
        job.Update();
        job.RunNow();
    
        current["JobId"] = job.Id;
        current.Update();
    
        RedrawUI();
      }
    

We’ve now completed the code required to implement our demonstration scenario. Deploy the project by selecting Deploy SalesProposalApplication from the Build menu.

Other -----------------
- SharePoint 2010 : Word Automation Services - Creating Conversion Jobs, Checking Status of Conversion Jobs
- SharePoint 2010 : The Client Object Model (part 4) - WebPart Communication Without Postbacks
- SharePoint 2010 : The Client Object Model (part 3) - Writing the JavaScript WebPart
- SharePoint 2010 : The Client Object Model (part 2) - Writing the Silverlight WebPart
- SharePoint 2010 : The Client Object Model (part 1) - Infrastructural Objects, Object Identity
- SharePoint 2010 : Making Enterprise Content Management Work - Records Management (part 2) - Configuring Enterprise Document and Records Management
- SharePoint 2010 : Making Enterprise Content Management Work - Records Management (part 1) - Record Declaration, Information Management Policies
- SharePoint 2010 : Making Enterprise Content Management Work - Document Management (part 3) - Document IDs, Managed Metadata
- SharePoint 2010 : Making Enterprise Content Management Work - Document Management (part 2) - Document Sets
- SharePoint 2010 : Making Enterprise Content Management Work - Document Management (part 1) - Item-level Security, Versioning Settings
- SharePoint 2010 : Setting Lockdown Mode for publishing sites, Configuring Site Collection audit settings, Accessing security policy reports
- SharePoint 2010 : Checking effective permission user interface
- SharePoint 2010 : Adding a user via PowerShell, Delegating PowerShell permissions
- SharePoint Server 2010 Business Intelligence Platform (part 6) - Reporting Services
- SharePoint Server 2010 Business Intelligence Platform (part 5) - PowerPivot
- SharePoint Server 2010 Business Intelligence Platform (part 4) - PerformancePoint Services - Time Intelligence, Decomposition Tree
- SharePoint Server 2010 Business Intelligence Platform (part 3) - PerformancePoint Services - Create a Dashboard
- SharePoint Server 2010 Business Intelligence Platform (part 2) - PerformancePoint Services - Using PerformancePoint Within a Site, Dashboard Designer, PerformancePoint Data Connections
- SharePoint Server 2010 Business Intelligence Platform (part 1) - Business Intelligence Web Parts
- SharePoint 2010 : Writing Workflows with Visual Studio
 
 
 
Top 10
 
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
- Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
- Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
- First look: Apple Watch

- 3 Tips for Maintaining Your Cell Phone Battery (part 1)

- 3 Tips for Maintaining Your Cell Phone Battery (part 2)
programming4us programming4us
Video Tutorail Microsoft Access Microsoft Excel Microsoft OneNote Microsoft PowerPoint Microsoft Project Microsoft Visio Microsoft Word Active Directory Biztalk Exchange Server Microsoft LynC Server Microsoft Dynamic Sharepoint Sql Server Windows Server 2008 Windows Server 2012 Windows 7 Windows 8 Adobe Indesign Adobe Flash Professional Dreamweaver Adobe Illustrator Adobe After Effects Adobe Photoshop Adobe Fireworks Adobe Flash Catalyst Corel Painter X CorelDRAW X5 CorelDraw 10 QuarkXPress 8 windows Phone 7 windows Phone 8 BlackBerry Android Ipad Iphone iOS
Celebrity Style, Fashion Trends, Beauty and Makeup Tips.