我正在使用sharepoint 2010,我要做的是采用word文档模板,对几个关键词进行替换(例如:将##ClientID##
替换为客户端的id)并保存在sharepoint上的库中具有特定名称。
我已经想出如何在具有word interop的本地计算机上执行此操作,但是interop库这个词并非旨在作为服务运行。然后我发现Word Automation Services似乎做了我需要做的事情。但是,我在互联网上找到的每个例子(包括这里的SO)都只是“如何使用Microsoft.Office.Word.Server.Conversions
命名空间从word文档转换为xxx”。我还没有找到关于如何使用Microsoft.Office.Word.Server.Service
命名空间对文档进行查找和替换的示例。 MSDN非常缺乏如何使用这些类,我不知道从哪里开始使用它。
是不是可以使用这些服务来做我想做的事情?如果可以做到,有人能指出我正确的方向去做我想做的事吗?
答案 0 :(得分:3)
Word Automation Services似乎不是我想用来做我想做的事情,我需要的是Open XML SDK。
更新: 这里是关于如何对文档进行替换的代码,在我的文本中我想替换富文本框中的位置。所以这就是我在SdtRun里面看的原因。
public FileDetails GetOrGenerateChecklist(string PracticeName, string ContractID, string EducationDate, string MainContactInfo, string Address)
{
if (String.IsNullOrEmpty(PracticeName) || String.IsNullOrEmpty(ContractID))
return null;
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(
"<Where><Eq>",
"<FieldRef Name='FileLeafRef'/>",
"<Value Type='File'>", PracticeName, " - ", ContractID, ".docx</Value>",
"</Eq></Where>");
var items = list.GetItems(query);
//if document exists return existing document.
if (items.Count > 0)
return new FileDetails() { Address = String.Concat(web.Url, "/Educator Checklists/", PracticeName, " - ", ContractID, ".docx"), LastModified = (DateTime)items[0]["Modified"]};
//Begin transforming form template to document.
MemoryStream documentStream;
//copy the stream to memory
using (Stream tplStream = web.GetFile(templetAddr).OpenBinaryStream())
{
documentStream = new MemoryStream((int)tplStream.Length);
CopyStream(tplStream, documentStream);
documentStream.Position = 0L;
}
using (WordprocessingDocument template = WordprocessingDocument.Open(documentStream, true))
{
template.ChangeDocumentType(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);
if(!String.IsNullOrEmpty(EducationDate))
ReplaceText(mainPart, "#EducationDate#", EducationDate);
if(!String.IsNullOrEmpty(MainContactInfo))
ReplaceText(mainPart, "#MainContactInfo#", MainContactInfo);
if(!String.IsNullOrEmpty(Address))
ReplaceText(mainPart, "#Address#", Address);
}
documentStream.Position = 0L;
try
{
list.RootFolder.Files.Add(String.Concat(PracticeName, " - ", ContractID, ".docx"), documentStream);
}
catch(SPException)
{
return null;
}
return new FileDetails() { Address = String.Concat(web.Url, "/Educator Checklists/", PracticeName, " - ", ContractID, ".docx"), LastModified = DateTime.Now };
}
private static void CopyStream(Stream source, Stream destination, int bufferSize = 0x1000)
{
int num;
byte[] buffer = new byte[bufferSize];
while ((num = source.Read(buffer, 0, buffer.Length)) != 0)
{
destination.Write(buffer, 0, num);
}
}
private static void ReplaceText(MainDocumentPart docPart, string match, string value)
{
if (value == null)
value = String.Empty;
var sdtr = docPart.Document.Descendants<SdtRun>();
foreach (var sdt in sdtr)
{
if (sdt.InnerText == match)
{
Text txt = new Text(value);
//using the sdt.FirstChild.FirstChild.CloneNode(true) will copy the text formatting of the old text.
var newtext = new SdtContentRun(new Run(sdt.FirstChild.FirstChild.CloneNode(true), txt));
sdt.SdtContentRun.RemoveAllChildren();
sdt.SdtContentRun.InsertAt(newtext, 0);
}
}
}