使用C#将Word文档转换为文本文档

4
我正在尝试将一个word文档(.doc)转换为文本文档,以便能够使用正则表达式在文档中查找内容。我编写了以下代码,将word文档转换为富文本格式(通过将其添加到富文本框),但这并没有转化为纯文本格式。当我用普通文本文档尝试时,它会将每个单词打印在新行上。我没有找到任何关于如何在C#中实现这一点的信息。我正在使用C#和Visual Studio 2010。
我不希望在文档中出现特殊字符(如粗体、下划线等),但如果有人知道如何提取这些字符并使其更加健壮,那就太棒了。
我需要将其作为文本文档,因为我知道几种适用于常规文本的方法,但我怀疑它们对于带有word文档中隐藏/特殊字符的文本可能无法正常工作。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.Office.Interop.Word;

namespace ReadWordDocProject
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            string testFile = @"C:\Users\<mycomputer>\Documents\TestItemHelpers\TestWordDoc.docx";

            Microsoft.Office.Interop.Word.Application application = new Microsoft.Office.Interop.Word.Application();
            Document document = application.Documents.Open(testFile);//path here

            int count = document.Words.Count;
            for (int i = 1; i <= count; i++)
            {
                string text = document.Words[i].Text;
                //Do output with text here
                richTextBox1.AppendText(text);
            }

            ((_Application)application).Quit(); //cast as _Application because there's ambiguity 
        }


    }
}

当我尝试使用普通文本文档时,它会将每个单词打印在新的一行上。你在这里尝试的是什么代码? - Ben Aaronson
1
作为一种非编程解决方案,您是否尝试过从Word中复制整个文档内容并将其粘贴到文本编辑器中?如果这只是一个一次性的任务,那肯定是最快的转换成纯文本文档的方法。 - adv12
我将会有很多类似这样的文件进来,手动处理似乎有点不切实际。我知道如何手动处理,但是希望能有一个更简单的解决方案。 - user3003304
@BenAaronson 我只是为了测试和查看它是否有效,将一行一行地写入文本文档。你认为Word文档中的某些特殊字符是否可能会将一个文本等效行转换为Word文档的单个单词?... - user3003304
2个回答

4

微软表示您不应该在自动化应用程序中使用Microsoft Office Interop来操作文档。

您可以使用免费的库,比如Spire Doc将Word文档转换为TXT,然后打开txt文件。我认为有一种方法可以直接从Spire保存到MemoryStream,但我不确定。(我知道Aspose Words中有这个功能,但那不是免费的。)

private void button1_Click(object sender, EventArgs e)
{
    //Open word document
    Document document = new Document();
    string docPath = @"C:\Users\<computer name>\Documents\TestItemHelpers";

    document.LoadFromFile(Path.Combine(docPath,"TestWordDoc.docx"));

    //Save doc file.
    document.SaveToFile(Path.Combine(docPath,"TestTxt.txt"), FileFormat.Txt);

    string readText = File.ReadAllText(Path.Combine(docPath,"TestTxt.txt"));

    //do regex here
}

编辑:如果您要使用Interop,因为它对用户运行的活动没有问题(如评论中指出的那样),您可以将文档保存为文本文件,然后进行正则表达式匹配:
private void button1_Click(object sender, EventArgs e)
{
    string docPath = @"C:\Users\<computer name>\Documents\TestItemHelpers"
    string testFile = "TestWordDoc.docx";

    Microsoft.Office.Interop.Word.Application application = new Microsoft.Office.Interop.Word.Application();
    Document document = application.Documents.Open(Path.Combine(docPath,testFile );
    application.ActiveDocument.SaveAs(Path.Combine(docPath,"TestTxt.txt"), WdSaveFormat.wdFormatText, ref noEncodingDialog);
    ((_Application)application).Quit();

    string readText = File.ReadAllText(Path.Combine(docPath,"TestTxt.txt"));

    //do regex here
}

2
你的第一个链接仅适用于服务器端处理。对于用户运行的应用程序来说,这是完全可以接受的。 - crashmstr
我的程序可能会用于服务器端工作,所以这对我来说可能是完美的。 - user3003304
我添加了Interop SaveAs,以防你也对这种方式感兴趣。 - user1914368
1
有其他付费库可以读取超过100段落,但您可以使用此库进行测试。如果您要在服务器上使用它,则肯定需要使用其他东西而不是MS Word Interop。 - user1914368
Spire已经有一段时间没有更新了,有没有更现代的替代品? - gillonba
显示剩余2条评论

0
如果您不想使用Interop或像Spire这样的付费库,您可以使用NPOI。它是一个成熟的开源项目,用于处理Word和Excel文件。
请注意,Word文件可能具有复杂的结构,例如嵌套表格或合并/拆分的单元格。这就是为什么我认为NPOI没有明确的SaveAsText()方法的原因。但是,如果您只需要段落或表格中的文本,您可以像这样轻松提取它(.NET 6示例):
public static IEnumerable<string> WordFileToText(string wordFilePath)
{
    using var fileStream = File.OpenRead(wordFilePath);
    using var doc = new XWPFDocument(fileStream);
    var result = WordFileToText(doc);
    return result;
}

private static IEnumerable<string> WordFileToText(XWPFDocument doc)
{
    var result = new List<string>();
    foreach (var bodyElement in doc.BodyElements)
    {
        if (bodyElement is XWPFParagraph paragraph)
        {
            result.Add(paragraph.Text);
            continue;
        }
        if (bodyElement is not XWPFTable table)
            continue;

        foreach (var row in table.Rows)
        {
            var tableLine = new StringBuilder();
            foreach (var cell in row.GetTableCells())
            {
                foreach (var cellParagraph in cell.Paragraphs)
                {
                    tableLine.Append(cellParagraph.Text);
                    tableLine.Append("| ");
                }
            }
            result.Add(tableLine.ToString());
        }
    }
    return result;
}



网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接