Recently, we have found a requirement where we need to automate a document content field's update. I think OpenXML SDK has some samples in MSDN, but our intention was to use K2 blackpearl since it provides a template do this. So found an article in K2 underground like below:
http://www.k2underground.com/blogs/k2/archive/2012/06/04/how-to-automate-document-assembly-from-within-a-k2-process.aspx
Though this article has a good explanation to use K2 WordDocument template, this has only one field update and that too through from K2 wizard. However, in our requirement we had more than one content field to be updated. So, on word document template decided to customize it and write my own code so that I can use same K2 blackpearl APIs and get my work done. Here is what I have done:
Right click on the WordDocument event template, select View Code option and the click on Event Item, that opens the code file. In that you can lot of templates code showing with switch cases and conditions, but I have used a source document libary and a destination document library. Source document library will help you to store templates which have content fields (you can prepare with the help of above article link from K2 underground) and the destination document library will store the updated document for content fields. I took a loop which has a loop count equal to the number of content fields in the document template and for each content field I have a mapped value. For this sample I took 2 content fields and updated some values dynamically.
The code look like below:
For my convenience, I have removed other templates code inside this event code, but we can still keep that logic as part of this.
Also, if we understand the APIs nicely, we can use server code event template from K2 Tool box and add the above code in it. That way also it works fine, but using the word document template will guide us how to use it's document (OPENXML) APIs for doc operations.
Hope it helps others too!!!
http://www.k2underground.com/blogs/k2/archive/2012/06/04/how-to-automate-document-assembly-from-within-a-k2-process.aspx
Though this article has a good explanation to use K2 WordDocument template, this has only one field update and that too through from K2 wizard. However, in our requirement we had more than one content field to be updated. So, on word document template decided to customize it and write my own code so that I can use same K2 blackpearl APIs and get my work done. Here is what I have done:
Right click on the WordDocument event template, select View Code option and the click on Event Item, that opens the code file. In that you can lot of templates code showing with switch cases and conditions, but I have used a source document libary and a destination document library. Source document library will help you to store templates which have content fields (you can prepare with the help of above article link from K2 underground) and the destination document library will store the updated document for content fields. I took a loop which has a loop count equal to the number of content fields in the document template and for each content field I have a mapped value. For this sample I took 2 content fields and updated some values dynamically.
The code look like below:
private void ExecuteUpdateContent(Project_d5ff4cc5c544462496df8afb5a72a9a1.EventItemContext_5b01db313c294025905a3b5d8a27feb1 K2)
{
for (int i = 1; i <= 2; i++)
{
#region
string k2ServerConnStr = K2.Configuration.ServerConnectionString;
string outputSharepointUrl = K2.Configuration.OutputSharePointUrl;
string outputLocationType = K2.Configuration.OutputDocumentLocationType;
string temp = string.Empty;
if (i == 1)
{
temp = K2.Configuration.OutputContentControlName;
}
else
{
temp = "ID";
}
string contentControlName = temp;// K2.Configuration.OutputContentControlName;
string sourceLocationType = K2.Configuration.SourceLocationType;
string sourceFileName = K2.Configuration.SourceFileName;
string refFieldName = K2.Configuration.ReferenceFieldName;
bool addRefItem = K2.Configuration.AddReferenceToField;
List<IReferenceItem> referenceItems = null;
switch (sourceLocationType)
{
case "SharePointDocumentLibrary":
{
string sourceSPUrl = K2.Configuration.SourceSharePointUrl;
string sourceLibName = K2.Configuration.SourceLibraryName;
string sourceFolderName = K2.Configuration.SourceFolderName;
referenceItems = SharePointFileHelper.GetFilesReference(sourceSPUrl, sourceLibName, sourceFolderName, sourceFileName, k2ServerConnStr);
}
break;
// from text is a special case, the source files do not have to be retrieved
case "Text":
default:
break;
}
string outputfileName = K2.Configuration.OutputFileName;
switch (outputLocationType)
{
case "SharePointDocumentLibrary":
{
string outputlibraryName = K2.Configuration.OutputLibraryName;
string outputfolderName = K2.Configuration.OutputFolder;
byte[] file = SharePointFileHelper.LoadFile(outputSharepointUrl, outputlibraryName, outputfolderName, outputfileName, k2ServerConnStr);
WordDocumentHelper wdHelper = new WordDocumentHelper(file);
byte[] returnFile = null;
if (sourceLocationType == "Text")
{
string sourceText = K2.Configuration.SourceText + "1";
returnFile = wdHelper.UpdateContentControl(contentControlName, sourceText);
}
else
{
returnFile = wdHelper.UpdateContentControl(contentControlName, referenceItems);
}
SharePointFileHelper outputSpHelper = new SharePointFileHelper(outputSharepointUrl, k2ServerConnStr);
//outputSpHelper.Save(returnFile, outputlibraryName, outputfolderName, outputfileName);
outputSpHelper.Save(returnFile, outputlibraryName, outputfolderName, outputfileName);
}
break;
}
#endregion
}
}
For my convenience, I have removed other templates code inside this event code, but we can still keep that logic as part of this.
Also, if we understand the APIs nicely, we can use server code event template from K2 Tool box and add the above code in it. That way also it works fine, but using the word document template will guide us how to use it's document (OPENXML) APIs for doc operations.
Hope it helps others too!!!