如何处理将iText \ iTextSharp表拆分为两页的情况? [英] How to handle the case in which an iText\iTextSharp table is split into two pages?

查看:97
本文介绍了如何处理将iText \ iTextSharp表拆分为两页的情况?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用iTextSharp时出现以下问题.

I have the following problem using iTextSharp.

我正在将一些表格放入文档中.问题是,如果表内容不适合某个页面并进入另一页面,则我将覆盖第二个页面标题,因此出现以下情况:

I am putting some tables into my document. The problem is that if a table content not fit on a page and go into another page I have that it overwrite the second page header, so I have the following situation:

如您所见,我将在页面末尾插入一个表,该表分为两页,第二个页面标题被表内容覆盖.

As you can see I am inserting a table at the end of a page and this is split into two pages and the second page header is overwrite by the table content.

我想避免这种情况,但是我不知道该怎么办.

I want to avoid this situation but I don't know how have I to do.

我在想,也许我可以做以下事情之一:

I am thinking that maybe I can do one of the following things:

  1. 也许我可以检查元素是否完全进入页面.如果不创建一个新页面并将其放到这个新页面中(但是如果一个表需要多于一个页面,这可能是个问题,如果我有一个很大的表的话)

  1. Maybe I can check if an element completely enter into a page. If not create a new page and put it into this new page (but this can be a problem if a single table need more then one page, in the case if I have a very big table)

我允许将表格分为2页,但是在这种情况下,我在第二页的上部保留了一些页边距,以便正确显示页眉.

I allow that a table is split across 2 pages but in this case I left some margin spacing in the upper of the second page so the header is correctly shown.

或者我该怎么做才能解决这种情况?

Or what can I do to solve this situation?

Tnx

我已经通过以下方式添加了标题:

I have add the header in the following way:

  1. 我已经实现了创建名为 PdfHeaderFooter 的类,该类扩展了 PdfPageEventHelper 类并实现了其方法.
  1. I have implement create a class named PdfHeaderFooter that extends the PdfPageEventHelper class and that implements its methods.

这时其类包含以下方法:

At this time its class contains the following methods:

    // write on start of each page
    public override void OnStartPage(PdfWriter writer, Document document)
    {
        base.OnStartPage(writer, document);
        PdfPTable tabHead = new PdfPTable(3);
        tabHead.SetWidths(new int[] { 165, 205, 125 });
        
        //tabHead.TotalWidth = 460F;
        tabHead.TotalWidth = document.Right - document.Left;        // TotalWidth = 495
        tabHead.WidthPercentage = 98;


        PdfPCell cell1 = new PdfPCell(iTextSharp.text.Image.GetInstance(folderImages + "logoEarlyWarning.png"), true) { Border = PdfPCell.BOTTOM_BORDER };
        tabHead.AddCell(cell1);
        //tabHead.AddCell(new PdfPCell(new Phrase("CELL 1:")) { Border = PdfPCell.BOTTOM_BORDER, Padding = 5, MinimumHeight = 50, PaddingTop = 15, });
        
        tabHead.AddCell(new PdfPCell(new Phrase("")) { Border = PdfPCell.BOTTOM_BORDER, Padding = 5, MinimumHeight = 50, PaddingTop = 15 });

        if(_sourceId == "NVD")
        {
            iTextSharp.text.Image logo = iTextSharp.text.Image.GetInstance(folderImages + "nvdLogo.png");
            logo.ScalePercent(48f);
            //PdfPCell cell3 = new PdfPCell(iTextSharp.text.Image.GetInstance(folderImages + "nvdLogo.png"), true) { Border = PdfPCell.BOTTOM_BORDER, PaddingBottom = 25 };
            PdfPCell cell3 = new PdfPCell(logo) { Border = PdfPCell.BOTTOM_BORDER, PaddingLeft = 50 };
            tabHead.AddCell(cell3);
        }
        else if(_sourceId == "DeepSight")
        {
            PdfPCell cell3 = new PdfPCell(iTextSharp.text.Image.GetInstance(folderImages + "DSLogo.jpg"), true) { Border = PdfPCell.BOTTOM_BORDER };
            tabHead.AddCell(cell3);
        }
        //tabHead.AddCell(new PdfPCell(new Phrase("CELL 3:")) { Border = PdfPCell.BOTTOM_BORDER, Padding = 5, MinimumHeight = 50, PaddingTop = 15 });
      
        
        tabHead.WriteSelectedRows(0, -1, document.Left, document.Top, writer.DirectContent);
    }

    // write on end of each page
    public override void OnEndPage(PdfWriter writer, Document document)
    {
        base.OnEndPage(writer, document);

        int pageN = writer.PageNumber;      // numero della pagina corrente OK
        String text = "Page " + pageN + " of ";
        float len = bf.GetWidthPoint(text, 8);

        Rectangle pageSize = document.PageSize;
        
        cb.SetRGBColorFill(100, 100, 100);

        cb.BeginText();
        cb.SetFontAndSize(bf, 8);
        cb.SetTextMatrix(pageSize.GetLeft(40), pageSize.GetBottom(30));
        cb.ShowText(text);
        cb.EndText();

        cb.AddTemplate(template, pageSize.GetLeft(40) + len, pageSize.GetBottom(30));

        cb.BeginText();
        cb.SetFontAndSize(bf, 8);
        cb.ShowTextAligned(PdfContentByte.ALIGN_RIGHT,
            "Printed On " + PrintTime,
            pageSize.GetRight(40),
            pageSize.GetBottom(30), 0);
        cb.EndText();
    }

因此您可以看到广告, OnStartPage()方法在每个页面的开头添加页眉,而 OnEndPage()在每个页面的末尾添加页脚页面.

So ad you can see, the OnStartPage() method add the header at the beginning of each pages and the OnEndPage() add the footer at the end of each pages.

因此,从您的答复中我了解到,我必须执行以下步骤:

So from what I understand from your response I have to do the followings steps:

  1. 将标题插入从 OnStartPage()移动到 OnEndPage()
  2. 使用绝对位置将其放置在页面的上部.
  3. 在文档创建过程中,使用页眉高度设置上边距.
  1. Move the header insertion from OnStartPage() to OnEndPage()
  2. Use an absolute position for place it in the upper part of the pages.
  3. In the document creation use the header height to set the top margin.

对吗?

我试图按照您对我所说的去做,现在我有以下情况:

I tried to do as you say to me and now I have the following situations:

  1. 进入扩展了 PdfPageEventHelper PdfHeaderFooter 中,我已经删除了 OnStartPage()方法

  1. Into my PdfHeaderFooter that extends PdfPageEventHelper I have deleted the OnStartPage() method

我已将头表的创建移至 OnEndPage()方法中,现在该方法:

I have moved the header table creation into the OnEndPage() method that now it this one:

 // write on end of each page
 public override void OnEndPage(PdfWriter writer, Document document)
 {
     base.OnEndPage(writer, document);

     // HEADER:
     PdfPTable tabHead = new PdfPTable(3);
     tabHead.SetWidths(new int[] { 165, 205, 125 });

     //tabHead.TotalWidth = 460F;
     tabHead.TotalWidth = document.Right - document.Left;        // TotalWidth = 495
     tabHead.WidthPercentage = 98;

     PdfPCell cell1 = new PdfPCell(iTextSharp.text.Image.GetInstance(folderImages + "logoEarlyWarning.png"), true) { Border = PdfPCell.BOTTOM_BORDER };
     tabHead.AddCell(cell1);
     //tabHead.AddCell(new PdfPCell(new Phrase("CELL 1:")) { Border = PdfPCell.BOTTOM_BORDER, Padding = 5, MinimumHeight = 50, PaddingTop = 15, });

     tabHead.AddCell(new PdfPCell(new Phrase("")) { Border = PdfPCell.BOTTOM_BORDER, Padding = 5, MinimumHeight = 50, PaddingTop = 15 });

     if (_sourceId == "NVD")
     {
         iTextSharp.text.Image logo = iTextSharp.text.Image.GetInstance(folderImages + "nvdLogo.png");
         logo.ScalePercent(48f);
         //PdfPCell cell3 = new PdfPCell(iTextSharp.text.Image.GetInstance(folderImages + "nvdLogo.png"), true) { Border = PdfPCell.BOTTOM_BORDER, PaddingBottom = 25 };
         PdfPCell cell3 = new PdfPCell(logo) { Border = PdfPCell.BOTTOM_BORDER, PaddingLeft = 50 };
         tabHead.AddCell(cell3);
     }
     else if (_sourceId == "DeepSight")
     {
         PdfPCell cell3 = new PdfPCell(iTextSharp.text.Image.GetInstance(folderImages + "DSLogo.jpg"), true) { Border = PdfPCell.BOTTOM_BORDER };
         tabHead.AddCell(cell3);
     }
     //tabHead.AddCell(new PdfPCell(new Phrase("CELL 3:")) { Border = PdfPCell.BOTTOM_BORDER, Padding = 5, MinimumHeight = 50, PaddingTop = 15 });


     tabHead.WriteSelectedRows(0, -1, document.Left, document.Top, writer.DirectContent);

     float headerHeight = tabHead.CalculateHeights();



     // FOOTER:
     int pageN = writer.PageNumber;      // numero della pagina corrente OK
     String text = "Page " + pageN + " of ";
     float len = bf.GetWidthPoint(text, 8);

     Rectangle pageSize = document.PageSize;

     cb.SetRGBColorFill(100, 100, 100);

     cb.BeginText();
     cb.SetFontAndSize(bf, 8);
     cb.SetTextMatrix(pageSize.GetLeft(40), pageSize.GetBottom(30));
     cb.ShowText(text);
     cb.EndText();

     cb.AddTemplate(template, pageSize.GetLeft(40) + len, pageSize.GetBottom(30));

     cb.BeginText();
     cb.SetFontAndSize(bf, 8);
     cb.ShowTextAligned(PdfContentByte.ALIGN_RIGHT,
         "Printed On " + PrintTime,
         pageSize.GetRight(40),
         pageSize.GetBottom(30), 0);
     cb.EndText();
 }

现在您可以看到 OnEndPage()方法包含创建页眉和页脚.

As you can see now the OnEndPage() method contains the header and footer creation.

在我看来, tabHead (我的标题表)使用绝对定位是因为我有:

It seems to me that tabHead (my header table) use the absolute positioning because I have:

tabHead.WriteSelectedRows(0, -1, document.Left, document.Top, writer.DirectContent);

在创建文档的另一个类中,有以下一行:

In the other class where I create the document I have this line:

document = new iTextSharp.text.Document(iTextSharp.text.PageSize.A4, 50, 50, 30, 65);

因此页面为A4且上边距为30px.

so the pages are A4 and have 30px as upper margin.

但是我仍然有同样的问题.

But I still have the same problem.

如果我将30的值更改为80,它只是向下移动标头,留下白色的顶部,但不能解决问题.

If I change the 30 value with 80 it simply moves down the header leaving a white top but does not solve the problem.

我想念什么?怎么了?

推荐答案

我假定您正确添加了页眉.也就是说:您已经在页面事件中实现了onEndPage()方法(不是方法的 ),并且将标头添加到了绝对位置.在将标头添加到绝对位置时,您确切知道需要多少空间.

I assume that you are adding page headers correctly. That is: you have implemented the onEndPage() method in a page event (not the onStartPage() method) and you're adding the header at an absolute position. As you are adding the header at an absolute position, you know exactly how much space it takes.

创建文档对象时,请定义页面大小.否则,页面大小将为A4(595 x 842用户单位).您还可以定义边距.如果您不这样做,则两侧的边距将为半英寸(36个用户单位).

When you create a document object, you define a page size. If you don't, the page size will be A4 (595 x 842 user units). You also define margins. If you don't, the margins will be half an inch (36 user units) on either side.

表格拆分时,将遵守页面大小及其边距:iText不会在该区域放置表格的任何部分.

When a table splits, the page size and its margins are respected: iText won't put any part of the table in that area.

因此,解决方案很简单:正如您所了解的是页眉所需的空间一样,您要做的就是以页眉适合页边距的方式定义页边距.

Hence the solution is simple: as you know the space needed by the header, all you have to do is to define the margin in a way that the header fits into the margin.

问题更新后的更新:

1.

这是错误的:

// write on start of each page
public override void OnStartPage(PdfWriter writer, Document document)
{
    ...
    tabHead.WriteSelectedRows(0, -1, document.Left, document.Top, writer.DirectContent);
}

永远不要在OnStartPage()方法中添加任何内容.将将标头写入代码的代码移至OnEndPage()方法.

You should never add any content in the OnStartPage() method. Move the code that writes the header to the OnEndPage() method.

2.

您已经在使用绝对位置添加tabHead:您将其添加到坐标x = document.left; y = document.Top.

You are already using an absolute position to add tabHead: you are adding it at the coordinate x = document.left; y = document.Top.

您定义在绝对位置添加的文件的宽度百分比.这没有任何意义,请删除以下行:

You define a width percentage for a file that is added at an absolute position. That doesn't make any sense, remove the following line:

tabHead.WidthPercentage = 98;

但是,您正在浪费资源.例如:您在页面事件iTextSharp.text.Image.GetInstance(folderImages + "nvdLogo.png")中创建徽标.这意味着您要添加图像字节的次数与页面的次数相同,从而导致PDF文件中的信息过多(文件have肿).

However, you are wasting resources. For instance: you create the logo in the page event: iTextSharp.text.Image.GetInstance(folderImages + "nvdLogo.png"). This means that you are adding the image bytes as many times as you have pages, resulting in redundant info in the PDF file (you have a bloated file).

您可以通过在onEndPage()方法之外创建图像来优化过程.您甚至可以在该方法之外创建表.例如:在事件类中创建成员变量tabHead,然后在事件实现的构造函数或OnOpenDocument()方法中创建表(该方法仅被调用一次).在onEndPage()方法中重用表(和图像).

You can optimize the process by creating the images outside the onEndPage() method. You can even create the table outside that method. For instance: create a member variable tabHead in the event class and create the table either in the constructor of your event implementation or in the OnOpenDocument() method (that method only gets called once). Reuse the table (and the images) in the onEndPage() method.

现在,图像字节将仅在PDF文件中出现一次(您将获得很多KB),并且只需要创建一次表(浪费的CPU时间更少).

Now the image bytes will be present in the PDF file only once (you'll gain plenty of KBytes) and you'll only have to create the table once (less CPU-time wasted).

3.

一个更好的解决方案是在页面事件的外部 之前创建tabHead对象.定义总宽度时,您可以向表格询问其高度:

An even better solution is to create the tabHead object outside the page event and before you open the document. As you define a total width, you can ask the table for its height:

float h = tabHead.TotalHeight;

现在您可以使用h定义上边距:

Now you can use h to define the top margin:

document.SetMargins(36f, 36f, h, 36f);

请注意,在打开文档之前,在 之前设置边距非常重要.您还必须调整添加表格的坐标.例如:

Note that it is important to set the margins before you open your document. You'll also have to adapt the coordinate at which you add the table. For instance:

tabHead.WriteSelectedRows(0, -1, document.Left, document.Top + h, writer.DirectContent);

您对标头位置的评论表明,他们严重缺乏洞察力.

Your comment regarding the position of the header revealed a serious lack of insight.

这篇关于如何处理将iText \ iTextSharp表拆分为两页的情况?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆