Using the SharePoint 2010 Client OM with Open XML – Convert Wiki Page to Open XML Document

This is a clipboard friendly version of example #7, Convert Wiki Page to Open XML Document, from Using the SharePoint 2010 Managed Client Object Model with Open XML.

This blog is inactive.
New blog: EricWhite.com/blog

Blog TOC

using System;
using System.Linq;
using System.IO;
using System.Xml.Linq;
using Microsoft.SharePoint.Client;
using ClientOM = Microsoft.SharePoint.Client;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;

class RetrieveListItems
{
static void Main()
{
ClientContext clientContext =
new ClientContext("https://intranet.contoso.com");
List oList = clientContext.Web.Lists.GetByTitle("Eric's Wiki");
CamlQuery camlQuery = new CamlQuery();
camlQuery.ViewXml = @"<View/>";
ListItemCollection listItems = oList.GetItems(camlQuery);
clientContext.Load(
listItems,
items => items.Include(
item => item["FileLeafRef"],
item => item["WikiField"]));
clientContext.ExecuteQuery();

System.IO.File.Delete("WikiDocument.docx");
System.IO.File.Copy("EmptyDocument.docx", "WikiDocument.docx");
int altChunkIdCounter = 1;
int blockLevelCounter = 0;
bool first = true;
using (WordprocessingDocument myDoc =
WordprocessingDocument.Open("WikiDocument.docx", true))
{
MainDocumentPart mainPart = myDoc.MainDocumentPart;
mainPart.Document.Body.RemoveAllChildren<Paragraph>();
foreach (ClientOM.ListItem listItem in listItems)
{
string wikiPageTitleAspx = (string)listItem["FileLeafRef"];
string wikiPageTitle = wikiPageTitleAspx.Substring(
0, wikiPageTitleAspx.Length - 5);
if (first)
{
first = false;
mainPart.Document.Body.InsertAt(new Paragraph(
new ParagraphProperties(
new RunProperties(
new RunFonts()
{
AsciiTheme = ThemeFontValues.MajorHighAnsi,
HighAnsiTheme = ThemeFontValues.MajorHighAnsi
},
new Bold(),
new Color()
{
Val = "1F497D",
ThemeColor = ThemeColorValues.Text2
},
new FontSize() { Val = 28 },
new FontSizeComplexScript() { Val = 28 }),
new ParagraphStyleId() { Val = "Heading1" }),
new Run(
new RunProperties(
new RunFonts()
{
AsciiTheme = ThemeFontValues.MajorHighAnsi,
HighAnsiTheme = ThemeFontValues.MajorHighAnsi
},
new Bold(),
new Color()
{
Val = "1F497D",
ThemeColor = ThemeColorValues.Text2
},
new FontSize() { Val = 28 },
new FontSizeComplexScript() { Val = 28 }),
new Text(wikiPageTitle))),
blockLevelCounter++);
}
else
{
mainPart.Document.Body.InsertAt(new Paragraph(
new Run(
new Break() { Type = BreakValues.Page })),
blockLevelCounter++);
mainPart.Document.Body.InsertAt(new Paragraph(
new ParagraphProperties(
new RunProperties(
new RunFonts()
{
AsciiTheme = ThemeFontValues.MajorHighAnsi,
HighAnsiTheme = ThemeFontValues.MajorHighAnsi
},
new Bold(),
new Color()
{
Val = "1F497D",
ThemeColor = ThemeColorValues.Text2
},
new FontSize() { Val = 28 },
new FontSizeComplexScript() { Val = 28 }),
new ParagraphStyleId() { Val = "Heading1" }),
new Run(
new RunProperties(
new RunFonts()
{
AsciiTheme = ThemeFontValues.MajorHighAnsi,
HighAnsiTheme = ThemeFontValues.MajorHighAnsi
},
new Bold(),
new Color()
{
Val = "1F497D",
ThemeColor = ThemeColorValues.Text2
},
new FontSize() { Val = 28 },
new FontSizeComplexScript() { Val = 28 }),
new Text(wikiPageTitle))),
blockLevelCounter++);
}
XElement wikiField = XElement.Parse((string)listItem["WikiField"]);
XElement div = wikiField.Descendants("div").Where(e =>
(string)e.Attribute("class") == "ms-rte-layoutszone-inner")
.FirstOrDefault();
string html = String.Format(
"<html><head/><body>{0}</body></html>",
div != null ? div.ToString() : "");
string altChunkId = String.Format("AltChunkId{0}",
altChunkIdCounter++);
AlternativeFormatImportPart chunk =
mainPart.AddAlternativeFormatImportPart(
AlternativeFormatImportPartType.Xhtml, altChunkId);
using (Stream chunkStream = chunk.GetStream(FileMode.Create,
FileAccess.Write))
using (StreamWriter stringStream = new StreamWriter(chunkStream))
stringStream.Write(html);
AltChunk altChunk = new AltChunk();
altChunk.Id = altChunkId;
mainPart.Document.Body.InsertAt(altChunk,
blockLevelCounter++);
}
mainPart.Document.Save();
}
}
}