为有中文需求的客户提供多渠道中文技术支持.

Thu Jan 04, 2024 4:19 pm

请问用C# 如何做一个智能识别目录节点的功能

例如:只显示标题节点,不用显示正文内容,然后最好能不能把显示的节点,按照等级放到winform的树形框里,要有缩进的功能,各个节点等级对应上

第一章 供应商的综合实力
一、质量管理体系认证证书
二、职业健康安全管理体系认证证书
三、环境管理体系认证证书
第二章 供应商业绩
一、瑞安市玉海街道违章拆除、环境整治服务项目
二、瑞安市东山街道建筑物拆除、环境卫生乱点综合整治服务(第三期)

第三章 拟投入人员情况
第一节 团队人员
一、项目人员配置情况表
二、人员有相关资格(职称)证书
三、社保证明
第二节 投入人员的便捷性、稳定性、现场组织协调沟通能力措施
一、人员的便捷性措施
二、人员的稳定性措施
三、人员的现场组织协调沟通能力措施

jiao130456
 
Posts: 8
Joined: Mon Oct 09, 2023 9:29 am

Fri Jan 05, 2024 7:20 am

您好,

感谢您的询问。
通过最新商业版的Spire.Doc for .Net 11.12可以实现智能识别目录结点功能。
我把完整的代码放在下面供您参考:
Code: Select all
// 创建一个新的文档对象
Document doc = new Document();

// 从指定路径加载模板文件
doc.LoadFromFile(@"..\test.docx");
           
// 遍历文档的所有章节
foreach (Section section in doc.Sections)
{
    // 遍历章节中的所有文档对象
    foreach (DocumentObject obj in section.Body.ChildObjects)
    {
        // 如果文档对象是结构文档标签类型
        if (obj is StructureDocumentTag)
        {
            // 将文档对象转换为结构文档标签类型
            StructureDocumentTag tag = obj as StructureDocumentTag;
            // 遍历结构文档标签的子文档对象
            foreach (DocumentObject cObj in tag.ChildObjects)
            {
                // 如果子文档对象是段落类型
                if (cObj is Paragraph)
                {
                    // 将子文档对象转换为段落类型
                    Paragraph para = cObj as Paragraph;
                    // 如果段落的样式名称为TOC1(目录)
                    if (para.StyleName == "TOC1")
                    {
                        Console.WriteLine("一级目录:" + para.Text);
                    }
                    if (para.StyleName == "TOC2")
                    {             
                        Console.WriteLine("二级目录:" + para.Text);
                    }
                    if (para.StyleName == "TOC3")
                    {
                        Console.WriteLine("三级目录:" + para.Text);
                    }
                }
            }
        }
    }
}
// 定义输出文件名
string output = @"..\Change.docx";

// 将修改后的文档保存到指定的输出文件中,格式为Docx2013
doc.SaveToFile(output, FileFormat.Docx2013);

如果以上信息不能帮助您解决问题,请提供您的文件以帮助我们进行进一步调查,您可以附在此处或通过电子邮件发送给我们([email protected]).提前感谢。

Sincerely,
Ula
E-iceblue support team
User avatar

Ula.wang
 
Posts: 282
Joined: Mon Aug 07, 2023 1:38 am

Fri Jan 05, 2024 7:45 am

我想问下,这个word如果说在中间新增一个段落,那么他那个目录 也要跟随着新增的段落而变化。请问这个如何实现 程序自带这个功能吗??

jiao130456
 
Posts: 8
Joined: Mon Oct 09, 2023 9:29 am

Fri Jan 05, 2024 7:51 am

还有一个问题是 如何查看 某一个目录节点里面的段落。或者是导航到这个目录下面的段落

jiao130456
 
Posts: 8
Joined: Mon Oct 09, 2023 9:29 am

Fri Jan 05, 2024 10:27 am

您好,

感谢您的询问。
对于你提出的第一个问题,当你添加段落后您可以设置如下代码更新目录:
Code: Select all
//更新目录
doc.UpdateTableOfContents();

对于你提出的第二个问题,我们的产品支持查看某一个目录节点里面的段落功能,但是不支持导航到这个目录下面的段落功能
我把测试文档和完整的代码放在下面供您参考:
Code: Select all
    // 创建源文档对象
    Document sourceDocument = new Document();
    sourceDocument.LoadFromFile(@"E:\论坛\论坛35917\模拟文档.docx");

    // 创建目标文档对象
    Document destinationDoc = new Document();

    // 获取源文档的第一个节
    Spire.Doc.Section section = sourceDocument.Sections[0];

    // 在目标文档中添加一个新的节
    Spire.Doc.Section section1 = destinationDoc.AddSection();

    // 查找源文档中包含"供应商的综合实力"的所有文本选择
    TextSelection[] textSelections = sourceDocument.FindAllString("供应商的综合实力", false, true);

    // 查找源文档中包含"质量管理体系认证证书"的所有文本选择
    TextSelection[] textSelections1 = sourceDocument.FindAllString("质量管理体系认证证书", false, true);

    int index1 = 0;
    // 遍历textSelections数组,找到第一个不是"TOC1"样式的段落,并获取其在源文档中的索引
    foreach (TextSelection selection in textSelections)
    {
        if (selection.GetAsOneRange().OwnerParagraph.StyleName != "TOC1")
        {
            index1 = section.Body.Paragraphs.IndexOf(selection.GetAsOneRange().OwnerParagraph);
            Console.WriteLine(index1);
        }
    }

    int index2 = 0;
    // 遍历textSelections1数组,找到第一个不是"TOC2"样式的段落,并获取其在源文档中的索引
    foreach (TextSelection selection in textSelections1)
    {
        if (selection.GetAsOneRange().OwnerParagraph.StyleName != "TOC2")
        {
            index2 = section.Body.Paragraphs.IndexOf(selection.GetAsOneRange().OwnerParagraph);
            Console.WriteLine(index2);
        }
    }

    // 调用ExtractBetweenParagraphs方法,将源文档中指定范围内的段落复制到目标文档中
    ExtractBetweenParagraphs(sourceDocument, destinationDoc, index1, index2);

    // 将目标文档保存为文件
    destinationDoc.SaveToFile(@"..\Output14.docx", FileFormat.Docx);
}

private static void ExtractBetweenParagraphs(Document sourceDocument, Document destinationDocument, int startPara, int endPara)
{
    // 遍历源文档中指定范围内的段落,并将其复制到目标文档中
    for (int i = startPara + 2; i <= endPara; i++)
    {
        DocumentObject doobj = sourceDocument.Sections[0].Body.ChildObjects[i].Clone();
        destinationDocument.Sections[0].Body.ChildObjects.Add(doobj);
    }
}


Sincerely,
Ula
E-iceblue support team
User avatar

Ula.wang
 
Posts: 282
Joined: Mon Aug 07, 2023 1:38 am

Return to 中文技术支持