const string XELEMENT_XNAME_NAME = "Name"; const string XELEMENT_XNAME_DIRECTORY = "Directory"; const string XELEMENT_XNAME_FILENAME = "FileName"; const string XELEMENT_XNAME_FULLNAME = "FullName"; /// <summary> /// 要替换成超级链接的文本 /// </summary> const string REGEX_PATTERN_REFERTO = "Refer to [///"//“].+[///"//”]"; /// <summary> /// 获取双引号内的内容 /// </summary> const string REGEX_PATTERN_FILENAME = ".*[///"//“](.+)[///"//”].*"; /// <summary> /// 创建Word超链接 /// </summary> /// <param name="fileName"></param> public static void CreateHyperlink(string fileName) { using (WordprocessingDocument wdDoc = WordprocessingDocument.Open(fileName, true)) { MainDocumentPart wdMain = wdDoc.MainDocumentPart; Document document = wdMain.Document; // 文档所在目录。 DirectoryInfo rootDir = new DirectoryInfo(Path.GetDirectoryName(fileName)); string dirFullName = rootDir.FullName.EndsWith("//") ? rootDir.FullName : string.Format("{0}//", rootDir.FullName); string linkFileName = string.Empty; // rootDir目录下的文件目录结构。 XElement fileXmlTree = CreateFileSystemXmlTree(rootDir); var paragraphs = from p in document.Body.Descendants<Paragraph>() select p; // 定义需匹配的正则表达式,不区分大小写。 Regex regex = new Regex(REGEX_PATTERN_REFERTO, RegexOptions.IgnoreCase); // 循环匹配文档的所有段落。 foreach (var p in paragraphs) { // 获取每段的文字 var txt = p.LogicalChildrenContent(typeof(Run)) .LogicalChildrenContent(typeof(Text)) .OfType<Text>() .Select(t => t.Text) .StringConcatenate(); if (txt.Length == 0) { continue; } // 检查段落文字中有无匹配项。 MatchCollection mc = regex.Matches(txt); // 找到匹配项,项将原段落文字删除。 if (mc.Count > 0) { p.RemoveAllChildren<Run>(); } // 循环匹配项,一个段落中可能需创建多个超链接。 foreach (Match ma in mc) { // 获取文件名 string name = Regex.Replace(ma.Value, REGEX_PATTERN_FILENAME, "$1"); // 查找是否存在实际的文档 var files = from f in fileXmlTree.Descendants(XELEMENT_XNAME_FILENAME) where f.Value == name select f; var file = files.FirstOrDefault(); if (file == null) { continue; } // 创建的超链接在段落文字中间时,需将之前删除的文字填充回来。 if (ma.Index > 0) { p.AppendChild(new Run(new Text(txt.Substring(0, ma.Index)))); } // 创建超链接 Hyperlink newHyperling = p.AppendChild( new Hyperlink( new ProofError() { Type = ProofingErrorValues.GrammarStart }, new Run( new RunProperties( new RunStyle() { Val = "Hyperlink" }), new Text(name) )) { History = false, Id = string.Format("rId{0}", DateTime.Now.Ticks.ToString()) }); // 填充超链接后面的文字。 if (txt.Length > ma.Index + ma.Length) { p.AppendChild(new Run(new Text(txt.Substring(ma.Index + ma.Length)))); } // 相对路径 string url = file.Attribute(XELEMENT_XNAME_FULLNAME).Value.Replace(dirFullName, string.Empty); // 设置超链接的URL(相对路径) wdMain.AddHyperlinkRelationship(new Uri(url, UriKind.Relative), true, newHyperling.Id); } } } } /// <summary> /// 获取目录和文件的树状结构 /// </summary> /// <param name="parentDir">上级目录</param> /// <returns></returns> private static XElement CreateFileSystemXmlTree(DirectoryInfo parentDir) { return new XElement(XELEMENT_XNAME_DIRECTORY, new XAttribute(XELEMENT_XNAME_NAME, parentDir.Name), from d in parentDir.GetDirectories() select CreateFileSystemXmlTree(d), from fi in parentDir.GetFiles() select new XElement(XELEMENT_XNAME_FILENAME, fi.Name, new XAttribute(XELEMENT_XNAME_FULLNAME, fi.FullName) ) ); }