【问题标题】:I can't insert something as "Page X of Y" into my PDF footer using iTextSharp我无法使用 iTextSharp 在 PDF 页脚中插入“Page X of Y”
【发布时间】:2014-07-26 14:56:25
【问题描述】:

我是 iTextSharp 的新手,我遇到以下情况:我正在创建一个包含页眉和页脚的 PDF(对于创建页眉和页脚,我正在使用扩展 PdfPageEventHelper 的类我已经覆盖了 OnStartPage()OnEndPage() 方法,它工作正常)。

现在我的问题是我必须在页脚中插入 Page X of Y。其中X**是**当前页码Y总页码。 Y 的值不是固定的(因为我的 PDF 的长度是事先不知道的,因为它取决于内容的长度,并且可能因 PDF 而异)。我该如何处理这种情况? (在每个页脚中插入正确的 Y 值?)

在线搜索我找到了这个教程(这是针对Java iText的,但可能与iTextSharp版本没有太大区别):http://itextpdf.com/examples/iia.php?id=104

在本例中,它创建了一个 PDF,其标题包含类似 Page X of Y 的内容。

我正在尝试理解这个示例(并将其翻译为 iTextSharp),但我对它的工作原理有一些疑问(以及它是否能真正解决我的问题)。

据我了解,它执行以下操作:

在扩展 PdfPageEventHelper 的类中,它被声明为 PdfTemplate 对象

PdfTemplate total;

我认为它可能处理了我的 PDF 文档中的总页数,但是阅读官方文档我没有太多关于这个类到底做什么的信息:http://api.itextpdf.com/itext/com/itextpdf/text/pdf/PdfTemplate.html

我正在尝试在我的类中做类似的事情来扩展 PdfPageEventHelper,但我做不到。

这是我不工作的代码:

public class PdfHeaderFooter : PdfPageEventHelper
{

    // The template with the total number of pages:
    PdfTemplate total;

    private static int numPagina = 1;

    public Image CellImage;
    private string folderImages;
    private string _sourceId;


    public PdfHeaderFooter(string _folderImages, string sourceId)
    {
        folderImages = _folderImages;
        _sourceId = sourceId;

    }


    /* Creates the PdfTemplate that will hold the total number of pages.
     * Write on top of document
     * */
    public override void OnOpenDocument(PdfWriter writer, Document document)
    {

        base.OnOpenDocument(writer, document);

        // (Nobili) Page Number:
        total = writer.DirectContent.CreateTemplate(30, 16);

        //PdfPTable tabFot = new PdfPTable(new float[] { 1F });
        PdfPTable tabFot = new PdfPTable(2);
        tabFot.WidthPercentage = 98;
        tabFot.SpacingAfter = 10F;
        PdfPCell cell;
        //tabFot.TotalWidth = 300F;
        cell = new PdfPCell(new Phrase("Header"));
        tabFot.AddCell(cell);
        tabFot.WriteSelectedRows(0, -1, 150, 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;
        String text = "Page " + pageN + " of ";

        //PdfPTable tabFoot = new PdfPTable(new float[] { 1F });
        PdfPTable tabFoot = new PdfPTable(3);
        tabFoot.TotalWidth = document.Right - document.Left;

        tabFoot.DefaultCell.Border = PdfPCell.NO_BORDER;
        tabFoot.DefaultCell.CellEvent = new RoundedBorder();

        PdfPTable innerTable = new PdfPTable(2);
        innerTable.SetWidths(new int[] { 247, 246 });
        innerTable.TotalWidth = document.Right - document.Left;
        innerTable.DefaultCell.Border = PdfPCell.NO_BORDER;
        PdfPCell innerCellLeft = new PdfPCell(new Phrase("Early Warning - Bollettino")) { Border = PdfPCell.NO_BORDER, Padding = 5, MinimumHeight = 20, HorizontalAlignment = Element.ALIGN_LEFT };
        //PdfPCell innerCellRight = new PdfPCell(new Phrase("Pag. " + numPagina + "/5")) { Border = PdfPCell.NO_BORDER, Padding = 5, MinimumHeight = 20, HorizontalAlignment = Element.ALIGN_RIGHT };
        PdfPCell innerCellCenter = new PdfPCell(new Phrase(text)) { Border = PdfPCell.NO_BORDER, Padding = 5, MinimumHeight = 20, HorizontalAlignment = Element.ALIGN_RIGHT };
        PdfPCell innerCellRight = new PdfPCell(Image.GetInstance(total)) { Border = PdfPCell.NO_BORDER, Padding = 5, MinimumHeight = 20, HorizontalAlignment = Element.ALIGN_RIGHT };

        innerTable.AddCell(innerCellLeft);
        innerTable.AddCell(innerCellRight);

        tabFoot.AddCell(innerTable);

        tabFoot.WriteSelectedRows(0, -1, document.Left, document.Bottom, writer.DirectContent);

        numPagina++;
    }


    // 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("CELL 2:")) { 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 close of document
    public override void OnCloseDocument(PdfWriter writer, Document document)
    {
        base.OnCloseDocument(writer, document);
    }



}

}

我想在页脚中放入类似 Page X of Y 的内容,如教程中所示

我尝试做以下事情:

1) 我将 PdfTemplate total; 对象声明为我的类的字段,并将其初始化为我的 OnOpenDocument() 方法

 total = writer.DirectContent.CreateTemplate(30, 16);

2) 放入我的 OnEndPage() 方法中:

String text = "Page " + pageN + " of ";

我创建了下表来显示 Y 的第 X 页

PdfPCell innerCellLeft = new PdfPCell(new Phrase("Early Warning - Bollettino")) { Border = PdfPCell.NO_BORDER, Padding = 5, MinimumHeight = 20, HorizontalAlignment = Element.ALIGN_LEFT };
PdfPCell innerCellCenter = new PdfPCell(new Phrase(text)) { Border = PdfPCell.NO_BORDER, Padding = 5, MinimumHeight = 20, HorizontalAlignment = Element.ALIGN_RIGHT };
            PdfPCell innerCellRight = new PdfPCell(Image.GetInstance(total)) { Border = PdfPCell.NO_BORDER, Padding = 5, MinimumHeight = 20, HorizontalAlignment = Element.ALIGN_RIGHT };

但它不起作用并抛出异常

我的代码可能有什么问题?

【问题讨论】:

标签: c# pdf pdf-generation itextsharp itext


【解决方案1】:

您正在复制/粘贴代码,而没有阅读示例随附的文档。此外,您完全忽略了我书中示例的 C# 版本。我已经向 C# 开发人员支付了很多钱来移植这些示例。感觉这笔钱被扔掉了。您可以在此处找到您尝试移植自己的示例:http://tinyurl.com/itextsharpIIA2C05

错误 #1: 您在 OnStartPage() 方法中添加内容。那是禁止!这在许多地方都有记录。例如,参见从官方文档第 150 页复制的 this answer

FAQ 为什么不建议在onStartPage()方法中添加内容?你会记得在第 5.2.4 节中当前页面为空时,iText 会忽略 newPage() 调用。当您从代码中显式调用此方法时,将执行或忽略此方法,但它也多次在 iText 中隐式调用。重要的是它被空页忽略;否则,您最终会得到大量不想要的新页面,这些页面无意中留空。如果您在 onStartPage() 方法中添加内容,则始终存在出现不需要的页面的风险。考虑保留onEndPage() 方法来添加内容更安全。

错误 #2: 您在 OnOpenDocument() 方法中添加内容。为什么会有这样的意义?

错误 #3:您创建 total 对象是因为您想要创建一个可以添加到每个页面的占位符。一旦您知道总页数,您就想在该占位符上填写该数字。然而:我没有看到你在任何地方这样做。执行此操作的适当位置,显然是在OnCloseDocument() 甚至。这个事件是在文档关闭之前触发的,所以在那一刻,总页数是已知的。正如夏洛克·福尔摩斯所说,这是初级的,亲爱的!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多