通过C#代码轻松移除Word文档中的文本与图片水印

在 C# 中移除 Word 文档中的水印(包括文本水印图片水印),可以借助 ​Microsoft Office Interop Word​ 或者 ​Open XML SDK​ 来实现。
这里分别给出两种方法的思路和代码示例,并推荐更轻量、无需安装 Office 的 Open XML 方案。

图片[1]_通过C#代码轻松移除Word文档中的文本与图片水印_知途无界

方法一:使用 Microsoft Office Interop Word(需安装 Word)

这种方法直接操控 Word 应用程序,适合桌面端且有 Office 的环境。

1. 安装 NuGet 包

Install-Package Microsoft.Office.Interop.Word

2. 代码示例

using Word = Microsoft.Office.Interop.Word;

public void RemoveWatermarkInterop(string filePath)
{
    Word.Application wordApp = new Word.Application();
    wordApp.Visible = false;

    try
    {
        Word.Document doc = wordApp.Documents.Open(filePath);
        
        // 移除文本水印(通过页眉页脚)
        foreach (Word.Section section in doc.Sections)
        {
            Word.HeaderFooter header = section.Headers[Word.WdHeaderFooterIndex.wdHeaderFooterPrimary];
            Word.Shape watermarkShape = null;
            
            // 遍历页眉中的所有形状,查找水印
            foreach (Word.Shape shape in header.Shapes)
            {
                // 文本水印通常是艺术字或文本框,且名称可能为 "WordPictureWatermark" 或包含特定文本
                if (shape.Name.Contains("Watermark") || 
                    (shape.Type == Word.MsoShapeType.msoTextEffect && shape.TextFrame.HasText != 0))
                {
                    shape.Delete();
                }
                else if (shape.Type == Word.MsoShapeType.msoPicture)
                {
                    // 图片水印
                    shape.Delete();
                }
            }
        }

        // 另外,Word 内置的“文本水印”功能(设计 → 水印)实际是页眉中的一个艺术字
        // 也可以通过删除页眉中的特定文字来清除
        foreach (Word.Section section in doc.Sections)
        {
            Word.HeaderFooter header = section.Headers[Word.WdHeaderFooterIndex.wdHeaderFooterPrimary];
            if (header.Range.Text.Contains("CONFIDENTIAL") || header.Range.Text.Contains("草稿"))
            {
                header.Range.Delete();
            }
        }

        // 保存并关闭
        doc.Save();
        doc.Close();
    }
    finally
    {
        wordApp.Quit();
        System.Runtime.InteropServices.Marshal.ReleaseComObject(wordApp);
    }
}

缺点​:

  • 需要安装 Word
  • COM 对象需手动释放,容易内存泄漏
  • 不适合服务器端自动化

方法二:使用 Open XML SDK(推荐,无需 Office)

Open XML SDK 直接操作 .docx 文件(ZIP 包内的 XML),轻量且无依赖。

1. 安装 NuGet 包

Install-Package DocumentFormat.OpenXml

2. 移除文本水印思路

Word 的文本水印实际是放在 ​页眉 → 主文档部分 → Header → Paragraph → Run → Drawing → WordArt​ 或 ​Text Effect​ 中。
我们通过 LINQ to XML 删除这些元素。

3. 移除图片水印思路

图片水印是放在页眉的 w:pictwp:inline/pic:pic 中,同样在页眉 XML 里。

4. 完整代码(移除页眉中的水印形状和文字)

using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
using System.Linq;

public void RemoveWatermarkOpenXml(string filePath)
{
    using (WordprocessingDocument doc = WordprocessingDocument.Open(filePath, true))
    {
        var mainDocumentPart = doc.MainDocumentPart;
        if (mainDocumentPart == null) return;

        // 遍历所有 Section 的 HeaderPart
        foreach (var headerPart in mainDocumentPart.HeaderParts)
        {
            var header = headerPart.Header;

            // 1. 删除所有 Shape(图片水印和艺术字水印)
            var shapes = header.Descendants<DocumentFormat.OpenXml.Vml.Shape>().ToList();
            foreach (var shape in shapes)
            {
                shape.Remove();
            }

            // VML 图片(v:shape 另一种形式)
            var vShapes = header.Descendants<DocumentFormat.OpenXml.Vml.Office.Shape>().ToList();
            foreach (var shape in vShapes)
            {
                shape.Remove();
            }

            // 2. 删除 WordArt(文本水印)
            var textEffects = header.Descendants<DocumentFormat.OpenXml.Drawing.TextBody>().ToList();
            foreach (var te in textEffects)
            {
                // 简单判断:如果包含特定水印文字,删除整个段落
                if (te.InnerText.Contains("CONFIDENTIAL") || te.InnerText.Contains("草稿"))
                {
                    var paragraph = te.Ancestors<Paragraph>().FirstOrDefault();
                    paragraph?.Remove();
                }
            }

            // 3. 删除普通文字水印(在页眉段落中)
            foreach (var paragraph in header.Elements<Paragraph>())
            {
                if (paragraph.InnerText.Contains("CONFIDENTIAL") || paragraph.InnerText.Contains("草稿"))
                {
                    paragraph.Remove();
                }
            }
        }
    }
}

5. 注意事项

  • 此方法主要针对 ​页眉中的嵌入式水印​(最常见)。
  • 如果水印是通过 Word 的“设计→水印”添加的,它一定在页眉的 XML 中,上述代码可覆盖。
  • 对于复杂的自定义水印(如正文背景图片),需额外处理 document.body 的背景,但 Word 正文背景水印极少用。
  • 操作前建议备份原文件。

方法三:使用第三方库(Spire.Doc、Aspose.Words)

如果不想处理底层 XML,可用商业库,例如 ​Spire.Doc​:

// Spire.Doc 示例(需安装 Spire.Doc NuGet)
using Spire.Doc;

Document doc = new Document();
doc.LoadFromFile("input.docx");
foreach (Section section in doc.Sections)
{
    HeaderFooter header = section.HeadersFooters[HeaderFooterType.HeaderPrimary];
    if (header != null)
    {
        // 删除所有段落(简单粗暴)
        header.Paragraphs.Clear();
    }
}
doc.SaveToFile("output.docx", FileFormat.Docx2013);

优点:代码简单,支持复杂水印;缺点:商业收费。


总结

方法优点缺点适用场景
Interop Word操作简单,兼容性好需安装 Office,服务器不可用桌面工具,偶尔使用
Open XML SDK无需 Office,轻量,可服务器运行需了解 Word XML 结构服务端批量处理,推荐
第三方库代码简洁,功能强大商业授权企业项目,快速开发

推荐​:

  • 服务器端或无 Office 环境 → ​Open XML SDK
  • 桌面工具且已装 Office → ​Interop Word
  • 快速开发且可接受费用 → ​Spire.Doc / Aspose.Words
© 版权声明
THE END
喜欢就点个赞,支持一下吧!
点赞83 分享
评论 抢沙发
头像
欢迎您留下评论!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容