1. 生成目录并插入页码
using Microsoft.Office.Interop.Word;class Program{private void CreateTableOfContents(){Application wordApp = new ApplicationClass();var docPath = @"D:\1.docx";Document doc = wordApp.Documents.Open(docPath);// 获取文档中的目录对象TablesOfContents tablesOfContents = doc.TablesOfContents;int totalPages = puteStatistics(WdStatistic.wdStatisticPages, false);// 如果文档中已经存在目录,则删除它if (tablesOfContents.Count > 0){tablesOfContents[1].Delete();}var range = doc.Range(0, 0);//wordDoc.Content;// 在指定范围内插入目录Microsoft.Office.Interop.Word.TableOfContents toc = tablesOfContents.Add(range, true);// 设置目录标题的字体大小for (int i = 1; i <= toc.Range.Paragraphs.Count; i++){Microsoft.Office.Interop.Word.Paragraph paragraph = toc.Range.Paragraphs[i];paragraph.Range.Font.Size = 14;var sty = paragraph.Range.get_Style();}// 在目录开头插入目录标题Microsoft.Office.Interop.Word.Range tocTitleRange = doc.Range(0, 0); // 开头位置Microsoft.Office.Interop.Word.Paragraph tocTitleParagraph = doc.Content.Paragraphs.Add(tocTitleRange);tocTitleParagraph.Range.Text = "目录";tocTitleParagraph.Range.Font.Name = "Arial";tocTitleParagraph.Range.Font.Size = 20;tocTitleParagraph.Range.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphCenter;// 在目录末尾插入分页符Microsoft.Office.Interop.Word.Paragraph lastParagraph = toc.Range.Paragraphs[toc.Range.Paragraphs.Count - 1];Microsoft.Office.Interop.Word.Range separatorRange = lastParagraph.Range;separatorRange.Collapse(WdCollapseDirection.wdCollapseEnd);separatorRange.InsertBreak(WdBreakType.wdPageBreak);toc.Update();// 保存并关闭文档doc.SaveAs2();int totalPages1 = puteStatistics(WdStatistic.wdStatisticPages, false);// Go to page where page numbering should startobject missing = System.Reflection.Missing.Value;string pageNum = (totalPages1 - totalPages + 1).ToString();wordApp.Selection.GoTo(Microsoft.Office.Interop.Word.WdGoToItem.wdGoToPage, Microsoft.Office.Interop.Word.WdGoToDirection.wdGoToNext, ref missing, pageNum);Microsoft.Office.Interop.Word.Range rngPageNum = wordApp.Selection.Range;//Insert Next Page section break so that numbering can start at 1rngPageNum.InsertBreak(Microsoft.Office.Interop.Word.WdBreakType.wdSectionBreakNextPage);Microsoft.Office.Interop.Word.Section currSec = doc.Sections[rngPageNum.Sections[1].Index];Microsoft.Office.Interop.Word.HeaderFooter ftr = currSec.Footers[Microsoft.Office.Interop.Word.WdHeaderFooterIndex.wdHeaderFooterPrimary];//So that the footer content doesn't propagate to the previous sectionftr.LinkToPrevious = false;ftr.PageNumbers.RestartNumberingAtSection = true;ftr.PageNumbers.StartingNumber = 1;//If the total pages should not be the total in the document, just the section//use the field SectionPages instead of NumPagesobject TotalPages = Microsoft.Office.Interop.Word.WdFieldType.wdFieldSectionPages;object CurrentPage = Microsoft.Office.Interop.Word.WdFieldType.wdFieldPage;Microsoft.Office.Interop.Word.Range rngCurrSecFooter = ftr.Range;rngCurrSecFooter.Fields.Add(rngCurrSecFooter, ref CurrentPage, ref missing, false);rngCurrSecFooter.InsertAfter("/");rngCurrSecFooter.Collapse(Microsoft.Office.Interop.Word.WdCollapseDirection.wdCollapseEnd);rngCurrSecFooter.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphCenter;rngCurrSecFooter.Fields.Add(rngCurrSecFooter, ref TotalPages, ref missing, false);toc.Update();doc.SaveAs2();}}
2. 复制文档至另一文档最前面
private void BeforeInsert(){var path = System.IO.Directory.GetCurrentDirectory();string inputFile = $"{path}\\files\\1.docx";string tmplFile = $"{path}\\files\\2.docx";Application wordApp = new ApplicationClass();// 打开现有的 Word 文档Microsoft.Office.Interop.Word.Document wordDoc = wordApp.Documents.Open(inputFile);// 现有word前插入一页wordApp.Selection.InsertNewPage();// 打开复制的文档Microsoft.Office.Interop.Word.Document tmplDoc = wordApp.Documents.Open(tmplFile);// 复制到文档var range = wordDoc.Range(0, 0);tmplDoc = wordApp.Documents.Open(path);tmplDoc.Select();wordApp.Selection.Copy();range.PasteAndFormat(WdRecoveryType.wdFormatOriginalFormatting);wordDoc.SaveAs2();tmplDoc?.Close();wordDoc?.Close();object saveOption = Microsoft.Office.Interop.Word.WdSaveOptions.wdDoNotSaveChanges;wordApp?.Quit(ref saveOption, Type.Missing, Type.Missing);if (tmplDoc != default)System.Runtime.InteropServices.Marshal.ReleaseComObject(tmplDoc);if (wordDoc!= default)System.Runtime.InteropServices.Marshal.ReleaseComObject(wordDoc);if (wordApp != default){System.Runtime.InteropServices.Marshal.ReleaseComObject(wordApp);}}
3. 替换Word中的标记
/// <summary>/// 替换所有符合的text/// </summary>/// <param name="doc"></param>/// <param name="text"></param>/// <param name="replaceText"></param>public void ReplaceAll(ref Microsoft.Office.Interop.Word.Document doc, Dictionary<string, string> dic){//story ranges 里面保存了不同类型的story range, 每个story range可以通过NextStoryRange来获取同一类型下所有的story range。bool flag = true;foreach (Microsoft.Office.Interop.Word.Range storyRange in doc.StoryRanges){Microsoft.Office.Interop.Word.Range range = storyRange;while (range != null && flag){ReplaceAllText(range, dic);range = range.NextStoryRange;flag = false;}}}private void ReplaceAllText(Microsoft.Office.Interop.Word.Range range, Dictionary<string, string> dic){foreach (var item in dic){Microsoft.Office.Interop.Word.Find find = range.Find;find.ClearFormatting();find.Replacement.ClearFormatting();find.Text = item.Key;find.Replacement.Text = item.Value;find.Forward = true;find.Wrap = Microsoft.Office.Interop.Word.WdFindWrap.wdFindContinue;find.Format = false;find.MatchCase = true;find.MatchWholeWord = false;find.MatchWildcards = false;find.MatchSoundsLike = false;find.MatchAllWordForms = false;try{Console.WriteLine($"替换所有【{item.Key}】->【{item.Value}】!");find.Execute(find.Text, find.MatchCase, find.MatchWholeWord, find.MatchWildcards, find.MatchSoundsLike, find.MatchAllWordForms,find.Forward, find.Wrap, find.Format, find.Replacement.Text, Microsoft.Office.Interop.Word.WdReplace.wdReplaceAll, false, false, false, false);}catch (Exception ex){}}}
4. 设置页码
/// <summary>/// 增加页码/// </summary>/// <param name="app"></param>private void SetFooter(ref Microsoft.Office.Interop.Word.Application app){object missing = System.Reflection.Missing.Value;app.ActiveWindow.ActivePane.View.SeekView = Microsoft.Office.Interop.Word.WdSeekView.wdSeekCurrentPageFooter;app.ActiveWindow.ActivePane.Selection.Paragraphs.Alignment = Microsoft.Office.Interop.Word.WdParagraphAlignment.wdAlignParagraphCenter;Object CurrentPage = Microsoft.Office.Interop.Word.WdFieldType.wdFieldPage;app.ActiveWindow.Selection.Fields.Add(app.ActiveWindow.Selection.Range, ref CurrentPage, ref missing, ref missing);app.ActiveWindow.Selection.TypeText("/");Object TotalPages = Microsoft.Office.Interop.Word.WdFieldType.wdFieldNumPages;app.ActiveWindow.Selection.Fields.Add(app.ActiveWindow.Selection.Range, ref TotalPages, ref missing, ref missing);app.ActiveWindow.Selection.TypeText("\n");}/// <summary>/// 文档有目录时,从内容页开始增加页码/// </summary>/// <param name="doc"></param>/// <param name="wordApp"></param>/// <param name="startNumbering"></param>/// <returns></returns>private bool SetFooter(ref Microsoft.Office.Interop.Word.Document doc, ref Microsoft.Office.Interop.Word.Application wordApp, string startNumbering){try{// Go to page where page numbering should startobject missing = System.Reflection.Missing.Value;string pageNum = startNumbering;wordApp.Selection.GoTo(Microsoft.Office.Interop.Word.WdGoToItem.wdGoToPage, Microsoft.Office.Interop.Word.WdGoToDirection.wdGoToNext, ref missing, pageNum);Microsoft.Office.Interop.Word.Range rngPageNum = wordApp.Selection.Range;//Insert Next Page section break so that numbering can start at 1rngPageNum.InsertBreak(Microsoft.Office.Interop.Word.WdBreakType.wdSectionBreakNextPage);Microsoft.Office.Interop.Word.Section currSec = doc.Sections[rngPageNum.Sections[1].Index];Microsoft.Office.Interop.Word.HeaderFooter ftr = currSec.Footers[Microsoft.Office.Interop.Word.WdHeaderFooterIndex.wdHeaderFooterPrimary];//So that the footer content doesn't propagate to the previous sectionftr.LinkToPrevious = false;ftr.PageNumbers.RestartNumberingAtSection = true;ftr.PageNumbers.StartingNumber = 1;//If the total pages should not be the total in the document, just the section//use the field SectionPages instead of NumPagesobject TotalPages = Microsoft.Office.Interop.Word.WdFieldType.wdFieldSectionPages;object CurrentPage = Microsoft.Office.Interop.Word.WdFieldType.wdFieldPage;Microsoft.Office.Interop.Word.Range rngCurrSecFooter = ftr.Range;rngCurrSecFooter.Fields.Add(rngCurrSecFooter, ref CurrentPage, ref missing, false);rngCurrSecFooter.InsertAfter("/");rngCurrSecFooter.Collapse(Microsoft.Office.Interop.Word.WdCollapseDirection.wdCollapseEnd);rngCurrSecFooter.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphCenter;rngCurrSecFooter.Fields.Add(rngCurrSecFooter, ref TotalPages, ref missing, false);doc.SaveAs2();return true;}catch (Exception ex){_logger.LogError("SetPageIndexWithoutTableContent=>" + ex.Message + ex.StackTrace);return false;}}