Merging documents into a single document using Open XML SDK 2.0 and Word Automation Services
By peter.stilgoe
The code below will create a webpart that can be added to any document library, when the button ‘Merge Reports’ is clicked it will merge all the documents together in the library in to a single document using Open XML SDK & Word Automation Services.
You will need to add the following references:
DocumentFormat.OpenXml
Microsoft.Office.Word.Server
Microsoft.Sharepoint
Microsoft.Sharepoint.Client
Microsoft.Sharepoint.Client.Runtime
Windows.Base
using System;
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using System.Linq;
using System.IO;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using System.Text;
using Microsoft.SharePoint.Client;
using ClientOM = Microsoft.SharePoint.Client;
using Word = Microsoft.Office.Word.Server;
using Microsoft.Office.Word.Server.Conversions;
namespace DocumentMerge.VisualWebPart1
{
[ToolboxItemAttribute(false)]
public class VisualWebPart1 : WebPart
{
// Visual Studio might automatically update this path when you change the Visual Web Part project item.
private const string _ascxPath = @"~/_CONTROLTEMPLATES/DocumentMerge/VisualWebPart1/VisualWebPart1UserControl.ascx";
protected override void CreateChildControls()
{
System.Web.UI.Control control = Page.LoadControl(_ascxPath);
Controls.Add(control);
base.CreateChildControls();
Button btnSubmit = new Button();
btnSubmit.Text = "Merge Reports";
btnSubmit.Click += new EventHandler(OnSubmitClick);
Controls.Add(btnSubmit);
}
void OnSubmitClick(object sender, EventArgs e)
{
// String to store the output path
string outputPath = string.Format(@"{0}/masterreport-{1}.docx", SPContext.Current.RootFolderUrl, DateTime.Now.ToString("ddMMyyyy"));
// String containing the blank document part for our new DOCX
string strEmptyMainPart = "<?xml version='1.0' encoding='UTF-8' standalone='yes'?>" +
"<w:document xmlns:w='http://schemas.openxmlformats.org/wordprocessingml/2006/main'>" +
"<w:body><w:p><w:r><w:t></w:t></w:r></w:p></w:body></w:document>";
// In-memory stream for our consolidated WSR DOCX.
MemoryStream memOut = new MemoryStream();
// Out output document's OpenXML object
WordprocessingDocument outputDoc = WordprocessingDocument.Create(memOut, DocumentFormat.OpenXml.WordprocessingDocumentType.Document);
MainDocumentPart mainPart = outputDoc.AddMainDocumentPart();
Stream partStream = mainPart.GetStream();
UTF8Encoding encoder = new UTF8Encoding();
// Add our blank main part string to the newly created document
Byte[] buffer = encoder.GetBytes(strEmptyMainPart);
partStream.Write(buffer, 0, buffer.Length);
// Save the document in memory
mainPart.Document.Save();
SPListItemCollection files = SPContext.Current.List.Items;
int id = 1;
foreach (SPListItem item in files)
{
SPFile inputFile = item.File;
string altChunkId = "AltChunkId" + id;
id++;
byte[] byteArray = inputFile.OpenBinary();
AlternativeFormatImportPart chunk = outputDoc.MainDocumentPart.AddAlternativeFormatImportPart(AlternativeFormatImportPartType.WordprocessingML,
altChunkId);
using (MemoryStream mem = new MemoryStream())
{
mem.Write(byteArray, 0, (int)byteArray.Length);
mem.Seek(0, SeekOrigin.Begin);
chunk.FeedData(mem);
}
AltChunk altChunk = new AltChunk();
altChunk.Id = altChunkId;
outputDoc.MainDocumentPart.Document.Body.InsertAfter(altChunk,
outputDoc.MainDocumentPart.Document.Body.Elements<Paragraph>().Last());
outputDoc.MainDocumentPart.Document.Save();
}
outputDoc.Close();
memOut.Seek(0, SeekOrigin.Begin);
ClientContext clientContext = new ClientContext(SPContext.Current.Site.Url);
ClientOM.File.SaveBinaryDirect(clientContext, outputPath, memOut, true);
// Conversion
string docPath = string.Format(@"{0}{1}", SPContext.Current.Site.Url.Replace(@"\\", ""), outputPath);
//string pdfPath = docPath.Replace(".docx", ".pdf");
ConversionJobSettings JobSettings = new ConversionJobSettings();
JobSettings.OutputFormat = SaveFormat.Document;
JobSettings.OutputSaveBehavior = SaveBehavior.AlwaysOverwrite;
ConversionJob ConvJob = new ConversionJob("Word Automation Services", JobSettings);
ConvJob.UserToken = SPContext.Current.Site.UserToken;
ConvJob.AddFile(docPath, docPath);
ConvJob.Start();
}
}
}
More From pstilgoe
Change InfoPath View Before Uploading Form Using K2 Blackpoint
By peter.stilgoe
In your activity add a ‘Data Event Wizard’
Data Replication –> Transfer Data
Click ‘Assign’
Set the ‘Source’ as the name of the InfoPath view you want to switch to
Expand ‘_K2′ & set the ‘Destination’ to the ‘DocumentView’ field
Now when you save your form in a document library it will be saved on the view you set it as. Ideal for submitting forms as read only once the process is complete.



March 14th, 2011
