Microsoft.Office.Interop.Word 将表格添加到文档

问题描述 投票:0回答:2

我正在为 .NET Framework 4.8 编写一个 C# 实用程序库,用于自动创建 MS Word 文档。特别是,它挖掘 SQL Server 数据库并创建包含数据表的 Word 报告。

我似乎无法在文档中添加多个表格,除非它们位于单独的页面上(这很丑,因为它们很小)。我的各种尝试如下:

using Word = Microsoft.Office.Interop.Word;
// ... [other code] ...

// Create an instance of the Word application.
Word.Application wordApp = new Word.Application
{
    ShowAnimation = false,
    Visible = false
};
// Create a new Word document.
Word.Document document = wordApp.Documents.Add();

首先,尝试将两个表添加到文档本身的范围(失败):

// *Attempt 1*
// Get document range.
Word.Range docRange = document.Range();
// Add table 1.
Word.Table table = document.Tables.Add(docRange, 2, 3);
// Try to add table 2.
// Exception: "The range cannot be deleted"
Word.Table table2 = document.Tables.Add(docRange, 4, 5); // does not work

其次,尝试将两个表添加到文档第一部分的范围(失败):

// Get section range.
Word.Range secRange = document.Sections[document.Sections.Count].Range; // document.Sections.Count = 1
// Add table 1.
Word.Table table1 = document.Tables.Add(secRange, 2, 3);
// Try to add table 2.
Word.Table table2 = document.Tables.Add(secRange, 4, 5); // Exception: "The range cannot be deleted"

第三,尝试创建一个带有分页符的新部分,然后将每个表格添加到其自己的部分中(有效,但表格位于不同的页面上,这是我不想要的):

// Get section range.
Word.Range secRange = document.Sections[document.Sections.Count].Range; // document.Sections.Count = 1
// Add table 1.
Word.Table table1 = document.Tables.Add(secRange, 2, 3);
// Add a new section (with no arguments, a page-break will automatically be applied).
document.Sections.Add();
// Update section range.
secRange = document.Sections[document.Sections.Count].Range; // now document.Sections.Count = 2
// Add table 2 on a separate page.
Word.Table table2 = document.Tables.Add(secRange, 4, 5); // works

最后,尝试创建一个新的部分没有分页符(即,从前一个部分连续开始),然后将每个表添加到其自己的部分(失败):

// Get section range.
Word.Range secRange = document.Sections[document.Sections.Count].Range; // document.Sections.Count = 1
// Add table 1.
Word.Table table1 = document.Tables.Add(secRange, 2, 3);
// Add a new section without a page-break (have it come straight after the previous one).
object oRange = document.Sections[document.Sections.Count].Range; // document.Sections.Count = 1 still
object oStart = Word.WdSectionStart.wdSectionContinuous;
document.Sections.Add(oRange, oStart);
// Update section range.
secRange = document.Sections[document.Sections.Count].Range; // now document.Sections.Count = 2
// Try to add table 2.
Word.Table table2 = document.Tables.Add(secRange, 4, 5); // Exception: "The range cannot be deleted"

还有什么我可以尝试的吗?我不敢相信一个部分中不可能有多个表!但可以公平地说,我真的不知道我在这里做什么,也没有找到任何官方文档来解释其中的工作原理。

c# .net ms-word office-interop
2个回答
1
投票

这里的问题是 docRange 将被设置为“覆盖”文档的范围,例如如果文档为空,docRange.Start将为0,docRange.End将为1。添加“table”后,docRange.Start仍将为0,docRange.End将为9。因此,当您尝试添加table2时,您实际上是在要求 Word 删除“表格”并替换它,无论如何这都不是您想要的。 Word 不会这样做。

据我所知,没有“非常简单”的方法可以通过在文档末尾连续添加文本和/或对象序列来创建文档,并且范围对象有足够奇怪的行为,以至于并不总是很明显要做什么。我相信大多数人都会通过“附加多个对象”

创建 Range 对象
  • 对于每个对象,
  • 将 Range 对象“折叠”到文档末尾
    • 添加将一个对象与另一个对象分开所需的任何内容
    • 将 Range 对象“折叠”到文档末尾
    • 添加对象
  • 使用 VBA(我让您翻译为 c#,对您的初始示例的修复可能如下所示:

Sub insert2tables1() Dim docRange As Word.Range Dim table1 As Word.Table Dim table2 As Word.Table Set docRange = ActiveDocument.Range docRange.Collapse direction:=wdCollapseEnd Set table1 = docRange.Tables.Add(docRange, 2, 3) Set docRange = ActiveDocument.Range docRange.Collapse direction:=wdCollapseEnd docRange.InsertParagraph Set docRange = ActiveDocument.Range docRange.Collapse direction:=wdCollapseEnd Set table2 = docRange.Tables.Add(docRange, 5, 5) Set table2 = Nothing Set table1 = Nothing Set docRange = Nothing End Sub

上面的代码可以更短,但这不是重点。

我们在这里时关于 Range 对象的一些其他注意事项:

    当您从
  • point

    范围对象开始时(如上面的代码所示) 并将一个表添加到范围中,范围结束于 桌子。如果您随后尝试将另一个表添加到 that 范围,您 将创建一个嵌套在第一个表格的单元格内的表格。

  • Range 对象有多种方式将文本放入其中,例如Range.Text = "x"、Range.InsertBefore "x" 和 Range.InsertAfter "x",以及插入段落的各种方法(Range.InsertParagraph、Range.InsertParagraphBefore 和 Range.InsertParagraphAfter)。我的观点是,它们的行为并不像描述的那样,如果您要经常使用范围和对象,那么值得做一些测试,检查 Range.Start 和 Range.End 以了解实际发生的情况范围。
  • 某些对象类型具有特殊的“插入”方法来将它们插入到范围中。其他人使用“添加”。也许还值得看看在您需要使用的每种情况下范围会发生什么。
  • 最后,可能值得您按照 @user246821 的建议查看 OpenXml - 不确定是否已引用这些内容,但 Eric White 关于 OpenXMl 的页面
此处

可能有用,并且如果您可以通过简单的方式从 SQL 获取数据XML 格式,他的文档汇编器可能正是您所需要的 - 请参阅此页面,但我认为您可能需要检查 GitHub 以获取此材料的某些更高版本。


0
投票
user246821

发布的此链接提到的部分和段落的组合: // Create paragraph for the first table. Word.Paragraph paraTable1 = document.Paragraphs.Add(); // Add first table to this paragraph. Word.Table table1 = document.Tables.Add(paraTable1.Range, 2, 3); // Add space-filling paragraph. Word.Paragraph paraFiller = document.Paragraphs.Add(); paraFiller.Range.Text = $"{Environment.NewLine}{Environment.NewLine}"; paraFiller.Range.InsertParagraphAfter(); // Create paragraph for the second table. Word.Paragraph paraTable2 = document.Paragraphs.Add(); // Add second table to this paragraph. Word.Table table2 = document.Tables.Add(paraTable1.Range, 4, 5); // Add a new section with a page-break. document.Sections.Add(); // ... continue adding paragraphs and tables in the new section ...

© www.soinside.com 2019 - 2024. All rights reserved.