在页脚itext7条形码(itext7 barcodes in footer)

2019-10-30 09:14发布

我工作的一个相当复杂的解决方案,它采用类似HTML的输入,并将其转换为PDF。 一说我想解决的添加条形码的众多项目(所有类型的3月9日,PDF417和QR码)的文档页脚。

一对夫妇的细节,让我停留在如何实现:

  1. 条码将包含当前页码
  2. 条码将包含总页数
  3. 条码将里面其他iText的元素(如一个表格单元格或段)和(最终溶液)需要被提前解析出

了解这些细节,我挣扎于如何与条形码类似使用模板呈现的所有内容后,以取代页数Y的战略的第x页合并位。

我认为每个条形码都需要它自己的模板,因为的页数和跟踪的模板,直到所有的内容呈现,然后更新相应的条形码每一个人模板。 但由于页脚提前解析了,我需要一个代表一个条形码,这样页脚将有正确的高度和内容可适当调整的模板。

我相信,每个小部分需要在页面的结束事件处理程序进行处理,是一个正确的评估?

UPD编辑以包括代码示例。 我拿出相当多的其他的东西,我试图从这个例子来完成。 至于解析,而不是去在一个循环从1到20,并创建随机元素的时间提前,一些其他进程创建所有需要是存在于该文件,并会在元素的渲染该列表传递的元素。 这不包括页脚内容为好。 在这种情况下,我创建的HeaderHandler的构造函数的页脚表,因为这是接近相同的概念。 我提起这事的原因是,我将无法在处理程序的handleEvent创建表像在大多数例子我看到有关页脚表。 希望是有道理的。

void Main()
{
    PdfDocument pdf = new PdfDocument(new PdfWriter(Dest));
    PageSize pageSize = PageSize.A4;
    Document doc = new Document(pdf, pageSize,  true);
    HeaderHandler hh = new HeaderHandler(doc);

    ...
    some other object generation
    ... 

    // create random paragraphs to fill up multiple pages in the final solution this would have already happened.
    for (var i = 0; i < 20; i++)
        AddItemToList(elementList, i, objects);

    // add random elements back to the document 
    foreach (var e in elementList)
    {
        ... add each item just added to elementList to the document ...
    }

    renderer.Flush();

    hh.UpdateTotal(pdf);

    // I think I need to update all the barcodes and print them out here so that page count part of the barcode can be written


    doc.Close();
}

class HeaderHandler : IEventHandler
{
    Table Footer;
    Document Doc;

    public Margin First;
    public Margin Middle;
    public Margin Last;

    public Dictionary<int, Margin> PageMargins { get; set; }

    public float HeaderHeight { get; }
    public float FooterHeight { get; }

    PdfFormXObject PgCount;
    Text PageNumber;

    Dictionary<string, PdfFormXObject> BarcodeImages;   

    public HeaderHandler(Document doc)
    {
        Doc = doc;
        Footer = new Table(new float[] { 4, 2, 4}).SetAutoLayout();
        PageMargins = new Dictionary<int, Margin>();
        BarcodeImages = new Dictionary<string, PdfFormXObject>();

        var pageSize = Doc.GetPdfDocument().GetDefaultPageSize();
        var width = pageSize.GetRight() - pageSize.GetLeft() - Doc.GetLeftMargin() - Doc.GetRightMargin();

        // page total 
        PgCount = new PdfFormXObject(new Rectangle(0,0, 13, 13));

        Footer.AddCell(new Cell().Add(new Paragraph("info 1")));

        PageNumber = new Text("{page}");
        var cell = new Cell().Add(new Paragraph().Add(PageNumber).Add(" of ").Add(new Image(PgCount)).Add(" pages").SetTextAlignment(TextAlignment.CENTER));

        Footer.AddCell(cell);
        Footer.AddCell(new Cell().Add(new Paragraph("info 2")));
        Footer.AddCell("footer 1");
        Footer.AddCell("footer 2");

        //  I think I need to add a template here for the barcode as a placeholder so that when the renderersubtree is ran it provides space for the barcode
        Footer.AddCell(new Cell().Add(new Paragraph("{barcode} {qr code - {page} | {pagect} | doc name}")));

        TableRenderer fRenderer = (TableRenderer)Footer.CreateRendererSubTree();

        using (var s = new MemoryStream())
        {
            fRenderer.SetParent(new Document(new PdfDocument(new PdfWriter(s))).GetRenderer());
            FooterHeight = fRenderer.Layout(new LayoutContext(new LayoutArea(0, PageSize.A4))).GetOccupiedArea().GetBBox().GetHeight();
        }
    }

    public void UpdateTotal(PdfDocument pdf) {
        Canvas canvas = new Canvas(PgCount, pdf);
        canvas.ShowTextAligned(pdf.GetNumberOfPages().ToString(), 0, -3, TextAlignment.LEFT);
    }

    //draw footer and header tables 
    public void HandleEvent(Event e)
    {
        PdfDocumentEvent docEvent = e as PdfDocumentEvent;

        if (docEvent == null)
            return;

        PdfDocument pdf = docEvent.GetDocument();
        PdfPage page = docEvent.GetPage();
        PdfCanvas pdfCanvas = new PdfCanvas(page.GetLastContentStream(), page.GetResources(), pdf);
        int pageNum = pdf.GetPageNumber(page);
        var pageSize = Doc.GetPdfDocument().GetDefaultPageSize();

        Margin activeMargin = new Margin();

        if (PageMargins.ContainsKey(pageNum))
            activeMargin = PageMargins[pageNum];

        var width = pageSize.GetRight() - pageSize.GetLeft() - activeMargin.Left - activeMargin.Right;
        Header.SetWidth(width);
        Footer.SetWidth(width);

        var pageReferences = new List<TextRenderer>();

        // update page number text so it can be written to in the footer
        PageNumber.SetText(pageNum.ToString());

        // draw the footer
        rect = new Rectangle(pdf.GetDefaultPageSize().GetX() + activeMargin.Left, activeMargin.Bottom - GetFooterHeight(), 100, GetFooterHeight());
        canvas = new Canvas(pdfCanvas, pdf, rect);

        // I think it's here that I need to be able to add a barcode placeholder to something that can be called
        canvas.Add(Footer);
    }

    public float GetFooterHeight()
    {
        return FooterHeight;
    }
}
文章来源: itext7 barcodes in footer