使用 OpenXml 在 C# 中读取 docx 文件
Read a docx file in C# using OpenXml
我是 C# 和 OpenXml 的新手。我需要帮助阅读 .docx 文件并将每个段落存储在数组中。
我正在使用 OpenXml 读取 word(.docx) 文件。我能够读取文件并打印出来。但问题是我只能打印连接的段落。我找不到将每个段落存储为字符串数组的方法(就像在 Python 中使用 docx 库一样,您会自动将段落存储为字符串列表,我正在寻找类似的东西)。
using System;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
OpenWordprocessingDocumentReadonly(@"E:\WordDocTest\Test.docx");
}
public static void OpenWordprocessingDocumentReadonly(string filepath)
{
// Open a WordprocessingDocument based on a filepath.
using (WordprocessingDocument wordDocument =
WordprocessingDocument.Open(filepath, false))
{
// Assign a reference to the existing document body.
Body body = wordDocument.MainDocumentPart.Document.Body;
Console.WriteLine(body.InnerText);
wordDocument.Close();
}
}
}
}
Test.docx 看起来像这样
1。测试
这是测试 1。
测试 1 a.
2。 noTest
这是测试2。
我得到的输出是:TestThis is Test 1.Test1 part a.noTestThis is Test 2.
我想学习的是如何将每个段落或行存储在一个字符串数组中并能够遍历该数组。
@Nirakar Nepal 您可以尝试遍历 paras 列表并提取下一个兄弟,例如'foreach (var para in paras) { richTextBox1.Text += para.NextSibling().InnerText + "\n"; } ' 这当然假设您正在将输出打印到 richtextbox。这将显示标题之后发生的任何事情。您可以避免使用数组,而是释放 Openxml 与 Linq 和列表相结合的奇妙力量。如果你想处理段落,你可以像这样创建一个列表:
var paras = body.OfType<Paragraph>();
然后您可以使用 Where 将其扩展到 return 个特定元素,例如:
var paras = body.OfType<Paragraph>()
.Where(p => p.ParagraphProperties != null &&
p.ParagraphProperties.ParagraphStyleId != null &&
p.ParagraphProperties.ParagraphStyleId.Val.Value.Contains("Heading1")).ToList();
对于 return 标题后面的段落,您可以尝试循环遍历 paras 列表并提取下一个兄弟,例如
foreach (var para in paras) {
richTextBox1.Text += para.NextSibling().InnerText + "\n";
}
这当然假设您正在将输出打印到 richtextbox。这将显示标题之后发生的任何事情。同样,您的代码代码可以包含 .where 以过滤结果
我是 C# 和 OpenXml 的新手。我需要帮助阅读 .docx 文件并将每个段落存储在数组中。
我正在使用 OpenXml 读取 word(.docx) 文件。我能够读取文件并打印出来。但问题是我只能打印连接的段落。我找不到将每个段落存储为字符串数组的方法(就像在 Python 中使用 docx 库一样,您会自动将段落存储为字符串列表,我正在寻找类似的东西)。
using System;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
OpenWordprocessingDocumentReadonly(@"E:\WordDocTest\Test.docx");
}
public static void OpenWordprocessingDocumentReadonly(string filepath)
{
// Open a WordprocessingDocument based on a filepath.
using (WordprocessingDocument wordDocument =
WordprocessingDocument.Open(filepath, false))
{
// Assign a reference to the existing document body.
Body body = wordDocument.MainDocumentPart.Document.Body;
Console.WriteLine(body.InnerText);
wordDocument.Close();
}
}
}
}
Test.docx 看起来像这样
1。测试
这是测试 1。
测试 1 a.
2。 noTest
这是测试2。
我得到的输出是:TestThis is Test 1.Test1 part a.noTestThis is Test 2.
我想学习的是如何将每个段落或行存储在一个字符串数组中并能够遍历该数组。
@Nirakar Nepal 您可以尝试遍历 paras 列表并提取下一个兄弟,例如'foreach (var para in paras) { richTextBox1.Text += para.NextSibling().InnerText + "\n"; } ' 这当然假设您正在将输出打印到 richtextbox。这将显示标题之后发生的任何事情。您可以避免使用数组,而是释放 Openxml 与 Linq 和列表相结合的奇妙力量。如果你想处理段落,你可以像这样创建一个列表:
var paras = body.OfType<Paragraph>();
然后您可以使用 Where 将其扩展到 return 个特定元素,例如:
var paras = body.OfType<Paragraph>()
.Where(p => p.ParagraphProperties != null &&
p.ParagraphProperties.ParagraphStyleId != null &&
p.ParagraphProperties.ParagraphStyleId.Val.Value.Contains("Heading1")).ToList();
对于 return 标题后面的段落,您可以尝试循环遍历 paras 列表并提取下一个兄弟,例如
foreach (var para in paras) {
richTextBox1.Text += para.NextSibling().InnerText + "\n";
}
这当然假设您正在将输出打印到 richtextbox。这将显示标题之后发生的任何事情。同样,您的代码代码可以包含 .where 以过滤结果