How to get the stream for a template on a Document Library
I am trying to load the template file my SPDocumentLibrary
has set, do some transforms in OpenXML then save it back to the library as a document. I think I have all the steps down except reading the template. I don't know the "correct" way to open it (I could just use a WebClient to download it but it makes me feel dirty just typing that). Here is what I have so far.
public string GetOrGenerateChecklist(string PracticeName, string ContractID, string EducationDate, string MainContactInfo, string Address)
{
using (SPWeb web = SPContext.Current.Web)
{
SPDocumentLibrary list = (SPDocumentLibrary)web.Lists["Educator Checklists"];
var templetAddr = String.Concat(web.Url, '/', list.DocumentTemplateUrl);
SPQuery query = new SPQuery();
query.Query = string.Concat(
//Snip
);
var items = list.GetItems(query);
//if document exists return existing document.
if (items.Count > 0)
return String.Concat(web.Url, "/Educator Checklists/", PracticeName, " - ", ContractID, ".docx");
MemoryStream documentStream;
//copy the stream to memory
using (Stream tplStream = ????????) //<------- my problem
{
documentStream = new MemoryStream((int)tplStream.Length);
CopyStream(tplStream, documentStream);
documentStream.Position = 0L;
}
using (WordprocessingDocument template = WordprocessingDocument.Open(documentStream, true))
{
template.ChangeDo开发者_开发知识库cumentType(DocumentFormat.OpenXml.WordprocessingDocumentType.Document);
MainDocumentPart mainPart = template.MainDocumentPart;
mainPart.DocumentSettingsPart.AddExternalRelationship(
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/attachedTemplate",
new Uri(templetAddr, UriKind.Absolute));
ReplaceText(mainPart, "#PracticeName#", PracticeName);
ReplaceText(mainPart, "#EducationDate#", EducationDate);
ReplaceText(mainPart, "#MainContactInfo#", MainContactInfo);
ReplaceText(mainPart, "#Address#", Address);
}
documentStream.Position = 0L;
list.RootFolder.Files.Add(String.Concat(PracticeName, " - ", ContractID, ".docx"), documentStream);
return String.Concat(web.Url, "/Educator Checklists/", PracticeName, " - ", ContractID, ".docx");
}
}
So my question is how do i get the template stored at templetAddr
loaded in to the memory stream?
Also I am fairly new to sharepoint so if you see any other big mistakes I have made please let me know.
web.GetFile(templetAddr).OpenBinaryStream()
http://msdn.microsoft.com/en-us/library/ms476063.aspx (SPWeb.GetFile)
http://msdn.microsoft.com/en-us/library/ms470901.aspx (SPFile.OpenBinaryStream)
Here is a blog post that discusses some considerations when using the SharePoint object model to get an Open XML document, modify it, and put it back.
http://blogs.msdn.com/b/ericwhite/archive/2010/03/24/modifying-an-open-xml-document-in-a-sharepoint-document-library.aspx
Here is the smallest code to do so:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using Microsoft.SharePoint;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
class Program
{
static void Main(string[] args)
{
string siteUrl = "http://localhost";
using (SPSite spSite = new SPSite(siteUrl))
{
Console.WriteLine("Querying for Test.docx");
SPList list = spSite.RootWeb.Lists["Shared Documents"];
SPQuery query = new SPQuery();
query.ViewFields = @"<FieldRef Name='FileLeafRef' />";
query.Query =
@"<Where>
<Eq>
<FieldRef Name='FileLeafRef' />
<Value Type='Text'>Test.docx</Value>
</Eq>
</Where>";
SPListItemCollection collection = list.GetItems(query);
if (collection.Count != 1)
{
Console.WriteLine("Test.docx not found");
Environment.Exit(0);
}
Console.WriteLine("Opening");
SPFile file = collection[0].File;
byte[] byteArray = file.OpenBinary();
using (MemoryStream memStr = new MemoryStream())
{
memStr.Write(byteArray, 0, byteArray.Length);
using (WordprocessingDocument wordDoc =
WordprocessingDocument.Open(memStr, true))
{
Document document = wordDoc.MainDocumentPart.Document;
Paragraph firstParagraph = document.Body.Elements<Paragraph>()
.FirstOrDefault();
if (firstParagraph != null)
{
Paragraph testParagraph = new Paragraph(
new Run(
new Text("Test")));
firstParagraph.Parent.InsertBefore(testParagraph,
firstParagraph);
}
}
Console.WriteLine("Saving");
string linkFileName = file.Item["LinkFilename"] as string;
file.ParentFolder.Files.Add(linkFileName, memStr, true);
}
}
}
}
精彩评论