Aspose获取每页最后一个元素和所有元素

aspose word 如何获取每页最后一个元素和所有元素(CompositeNode),【 如果是跨页表格,能获取表格在当前页最后的行号】

@james_yeh_honlitech_com

Aspose.Words.Layout命名空间提供了一些类,当将文档格式化为页面时,这些类允许访问特定文档元素所处位置(例如,在页面上以及页面上的位置)的信息。

您可以使用LayoutCollector.GetStartPageIndex方法获取节点开始的页面的从1开始的索引,也可以使用LayoutCollector.GetEndPageIndex方法获取节点结束的页面的从1开始的索引。

您可以遍历文档的节点并使用这些方法来获得所需的输出。

非常感谢您的宝贵建议,我们在开发过程中还遇到了一个表续的问题,需要请教一下处理方式,问题如下:
aspose生成word文件, 可以根据当前word的表格和页面设置,自动生成“续表”功能。(如果表格跨页,自动截断表格,在第一页的表格上方段落显示“表1 XXXX”,在第二页的表格上方生成段落“表1续 XXXX”)

@james_yeh_honlitech_com

为了确保及时准确的响应,请在此处附加以下资源进行测试:

  • 您输入的Word文档。
  • 请附加显示意外行为的输出Word文件。
  • 请附加预期的输出Word文件,以显示所需的行为。
  • 请创建一个简单的应用程序(无编译错误的源代码),以帮助我们重现您的问题并将其附加到此处进行测试。

在您准备好这些信息后,我们将开始对您的问题进行调查,并为您提供更多信息。 谢谢您的合作。

PS:要附加这些资源,请压缩并上传它们。

File.zip (179.7 KB)
程序的源码比较大,请到百度网盘提取:
链接: https://pan.baidu.com/s/1h0pelyj79g8elrn8ksvvuw 提取码>: 6qi3

@james_yeh_honlitech_com

您共享的链接不再存在。

请创建一个简单的应用程序,以帮助我们最终重现您的问题并将其附加在此处进行测试。

微信图片_20191223091927.png (19.4 KB)
百度网盘地址永久有效的
https://pan.baidu.com/s/1h0pelyj79g8elrn8ksvvuw
提取码:6qi3

@james_yeh_honlitech_com

不幸的是,下载链接不可用。请在Dropbox上上传并共享链接。谢谢您的合作。

您好,我们是中国区的,您有邮箱吗?我邮箱发给您

Aspose.zip (9.7 MB)
bin.zip (4.1 MB)

请把压缩包Bin文件中的dll拷贝到asposexian项目bin文件中

@james_yeh_honlitech_com

根据我们的理解,您想在表开始之前插入文本“表1测试计划”,并且如果表拆分为多个页面,则要在另一页开始处插入文本“表1继续测试计划”。

在这种情况下,您可以拆分表并在表之前插入所需的文本。或者,您可以插入没有边框的新行,然后插入所需的文本。您可以通过执行以下提到的步骤来满足您的要求。

  1. 对表的第一行和最后一行使用LayoutCollector.GetStartPageIndex方法,以检查表是否分页。此方法返回节点的页面索引。
  2. 如果表格分成几页,请在第一行上方插入表格行,并插入文本“表格1测试计划”。
  3. 请遍历表的行。
  4. 将LayoutCollector.GetStartPageIndex用于表行并获取页码。
  5. 更改页码时,表示将表拆分为多个页面,请在拆分页面的行上方插入新行。
  6. 插入文本“表1继续测试计划”。

请检查以下代码示例。希望这对您有所帮助。

Document doc = new Document(MyDir + "模板文件.docx");
LayoutCollector collector = new LayoutCollector(doc);

Table table = doc.Sections[1].Body.Tables[0];

if (collector.GetStartPageIndex(table.FirstRow) != collector.GetStartPageIndex(table.LastRow))
{
    Row row = (Row)table.FirstRow.Clone(true);
    row.RemoveAllChildren();
    row.EnsureMinimum();
    row.FirstCell.FirstParagraph.Runs.Add(new Run(doc, "表1 试验计划"));

    double width = 0.0;
    foreach (Cell cell in table.FirstRow.Cells)
    {
        width += cell.CellFormat.Width;
    }

    row.FirstCell.CellFormat.Width = width;
    row.FirstCell.CellFormat.Borders.Left.LineWidth = 0.0;
    row.FirstCell.CellFormat.Borders.Right.LineWidth = 0.0;

    table.InsertBefore(row, table.FirstRow);
    collector = new LayoutCollector(doc);

    int page = collector.GetStartPageIndex(table.FirstRow);
    foreach (Row row1 in table.Rows)
    {
        if (page != collector.GetStartPageIndex(row1))
        {
            Row newRow = (Row)row.Clone(true);
            newRow.FirstCell.FirstParagraph.Runs[0].Text = "表1续 试验计划";
            table.InsertBefore(newRow, row1);
            collector = new LayoutCollector(doc);
        }

        page = collector.GetStartPageIndex(row1);
    }
}
             
doc.Save(MyDir + "19.12.docx");

非常感谢您,我先尝试一下

请问 在计算页面高度时,发现表格设置 AllowAutoFit 属性和 PreferredWidth 属性后,LayoutCollector 不能正确读到当前表格的结束位置。 (示例中应该在第5页结束的, 读出的结果为2)

            Document doc = new Document();
            // 添加表格
            Table table = new Table(doc);
            Row row = new Row(doc);
            table.Rows.Add(row);
            Paragraph cell1P = new Paragraph(doc);
            Cell cell1 = new Cell(doc);
            Run cellRun = new Run(doc);
            cellRun.Text = "wei";
            cell1P.AppendChild(cellRun);
            cell1.AppendChild(cell1P);
            row.AppendChild(cell1);

            Paragraph cell2P = new Paragraph(doc);
            Cell cell2 = new Cell(doc);
            Run cell2Run = new Run(doc);
            StringBuilder sbuilder = new StringBuilder();
            for (int i=0;i<3000; i++)
            {
                sbuilder.Append("早安");
            }
            cell2Run.Text = sbuilder.ToString();
            cell2P.AppendChild(cell2Run);
            cell2.AppendChild(cell2P);
            row.AppendChild(cell2);

            table.AllowAutoFit = true;
            table.PreferredWidth = PreferredWidth.FromPoints(467.8);
            doc.FirstSection.Body.AppendChild(table);

            Aspose.Words.Layout.LayoutCollector layout = new Aspose.Words.Layout.LayoutCollector(doc);
            layout.Clear();
            doc.UpdateFields();
            doc.UpdatePageLayout();
            Console.WriteLine(layout.GetEndPageIndex(cell2P));

            //layout.Clear();
            doc.UpdateFields();
            doc.UpdateTableLayout();
            doc.UpdateWordCount(true);
            layout = new Aspose.Words.Layout.LayoutCollector(doc);
            Console.WriteLine(layout.GetEndPageIndex(cell2P));

            //doc.Save(@"E:\work\data\tmp\tmp.docx");

@james_yeh_honlitech_com

请使用如下所示的CompatibilityOptions.GrowAutofit获得所需的输出。

doc.CompatibilityOptions.GrowAutofit = false;
//layout.Clear();
doc.UpdateFields();
doc.UpdateTableLayout();
doc.UpdateWordCount(true);
layout = new Aspose.Words.Layout.LayoutCollector(doc);
Console.WriteLine(layout.GetEndPageIndex(cell2P));

谢谢 :smile: 头疼了好久的问题呢, 感谢感谢

刚刚尝试了用 CompatibilityOptions 对象, 解决了表格超出 预定宽度的问题,但在这里还有一个问题:
我实际生成的文档,保存下来后查看,能得知表格所在的最后页码为5
但我用layoutCollecotr.GetEndPageIndex(table) 获取的最后页码为2
这里是什么导致的误差? 我在 CompatibilityOptions 对象中没有找到对应的数据处理设置。

抱歉补充下, 在做过些测试后,发现文档生成,
在保存为pdf的格式时,文档和layoutCollector显示一样, 表格没有按要求控制好宽度,已经变形。
在保存为word版本时, 格式完好, 但和 layoutCollector 给出的结果不一致,

@james_yeh_honlitech_com

我们使用下面的修改后的代码示例测试了该方案,并注意到LayoutCollector.GetEndPageIndex返回的值4是正确的。 表格的最后一个单元格在第4页上结束。

我们还为您的推荐信附上了输出PDF和DOCX。
Docs.zip (24.4 KB)

Document doc = new Document();
// 添加表格
Table table = new Table(doc);
Row row = new Row(doc);
table.Rows.Add(row);
Paragraph cell1P = new Paragraph(doc);
Cell cell1 = new Cell(doc);
Run cellRun = new Run(doc);
cellRun.Text = "wei";
cell1P.AppendChild(cellRun);
cell1.AppendChild(cell1P);
row.AppendChild(cell1);

Paragraph cell2P = new Paragraph(doc);
Cell cell2 = new Cell(doc);
Run cell2Run = new Run(doc);
StringBuilder sbuilder = new StringBuilder();
for (int i = 0; i < 3000; i++)
{
    sbuilder.Append("早安");
}
cell2Run.Text = sbuilder.ToString();
cell2P.AppendChild(cell2Run);
cell2.AppendChild(cell2P);
row.AppendChild(cell2);

table.AllowAutoFit = true;
table.PreferredWidth = PreferredWidth.FromPoints(467.8);
doc.FirstSection.Body.AppendChild(table);

Aspose.Words.Layout.LayoutCollector layout = new Aspose.Words.Layout.LayoutCollector(doc);
layout.Clear();
doc.UpdateFields();
doc.UpdatePageLayout();

doc.CompatibilityOptions.GrowAutofit = false;
layout.Clear();
doc.UpdateFields();
doc.UpdateTableLayout();
doc.UpdateWordCount(true);

layout = new Aspose.Words.Layout.LayoutCollector(doc);
Console.WriteLine(layout.GetEndPageIndex(cell2P));
doc.Save(MyDir + "out.docx");
doc.Save(MyDir + "out.pdf");