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 = doc.ComputeStatistics(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 = doc.ComputeStatistics(WdStatistic.wdStatisticPages, false);
// Go to page where page numbering should start
object 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 1
rngPageNum.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 section
ftr.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 NumPages
object 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 start
object 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 1
rngPageNum.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 section
ftr.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 NumPages
object 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;
}
}