当前位置: 首页 > 知识库问答 >
问题:

特定页面上的处理台计数器

公冶才
2023-03-14

我在itext7图书馆工作。我想做一个放在桌子上面的台面。问题出现在包含表格的每一页上。它绘制下一个表的编号。这就是结果。你可以看到表1的结尾,但表的顶部是2等等。

public class TabPageHandler : IEventHandler
{
    public string number { get; set; }
    public TabPageHandler(string number)
    {
        this.number = number;
    }


    public void HandleEvent(Event @event)
    {
        PdfDocumentEvent docEvent = (PdfDocumentEvent)@event;
        PdfDocument pdfDoc = docEvent.GetDocument();
        PdfPage page = docEvent.GetPage();
        int pageNumber = pdfDoc.GetPageNumber(page);

        PdfCanvas canvas = new PdfCanvas(page.NewContentStreamBefore(), page.GetResources(), pdfDoc);

        canvas.BeginText().MoveText(page.GetPageSize().GetWidth() / 2, page.GetPageSize().GetTop() - 35)
            .SetFontAndSize(PdfFontFactory.CreateFont(FontConstants.TIMES_ROMAN), 10)
            .ShowText("Number of page " + pageNumber)
            .EndText();

        canvas.BeginText().MoveText(20, page.GetPageSize().GetTop() - 20)
            .SetFontAndSize(PdfFontFactory.CreateFont(FontConstants.TIMES_ROMAN), 10)
            .ShowText("Table:" + number)
            .EndText();

        canvas.Release();
    }
}

public static void Main()
    {
        PdfDocument pdfDoc = new PdfDocument(new PdfWriter(DEST));
        Document doc = new Document(pdfDoc, PageSize.A4, true);
        for (int i = 1; i < 5; i++)
        {
            pdfDoc.RemoveAllHandlers();
            pdfDoc.AddEventHandler(PdfDocumentEvent.END_PAGE, new TabPageHandler(i.ToString()));
            Table table = new Table(UnitValue.CreatePercentArray(1)).UseAllAvailableWidth();
            table.AddHeaderCell(new Paragraph(i.ToString()));
            for (int j = 0; j < 40 * i; j++)
            {
                table.AddCell(new Paragraph("aaa"));
            }
            doc.Add(table);
            doc.Add(new AreaBreak(AreaBreakType.NEXT_PAGE));
        }
        doc.Close();
    }

共有1个答案

慕宪
2023-03-14

不幸的是,由于以下原因,提议的事件处理程序无法使用:即使创建了一个PdfDocument,将InstateFlush设置为true(顺便说一句,它是它的默认值,还有Pagesize. A4,因此不需要指定它),iText不会在下一个页面添加到文档时刷新页面(关闭一个页面并发送一个END_PAGE事件)。相反,iText会等待另一个页面被刷新。

因此,在处理这一行时,会调用第一页的事件:

            doc.add(new AreaBreak(AreaBreakType.NEXT_PAGE));

在处理这一行时调用第二页的事件(当i等于2时):

doc.add(table);

我建议重写您的事件处理程序。例如,为什么不在处理程序中添加一个map,其中key将表示表出现的第一页和值——表的编号和发生表的最后一页。然后在处理程序的级别上,您可以执行以下操作:每当事件被调度时,您应该在map中搜索以查找a)页面上是否有要刷新的表;如果是,它是哪个表。

下面的处理程序对此负责(请注意,代码部分在Java,但我相信移植到. NET应该没有问题):

    public class TabPageHandler implements IEventHandler {

    private Map<Integer, PageSpan> tables;

    public TabPageHandler() {
        this.tables = new HashMap<Integer, PageSpan>();
    }

    public void addTable(int table, int firstPage, int lastPage) {
        tables.put(firstPage, new PageSpan(table, lastPage));
    }

    int getTable(int page) {
        int firstPage = 0;
        for (int i = page; i > 0; i--) {
            if (null != tables.get(i)) {
                firstPage = i;
                break;
            }
        }
        if (0 == firstPage || tables.get(firstPage).getLastPage() < page) {
            // no table on such a page
            return -1;
        } else {
            return tables.get(firstPage).getTableNum();
        }
    }

    @Override
    public void handleEvent(Event event) {
        try {
            PdfDocumentEvent docEvent = (PdfDocumentEvent) event;
            PdfDocument pdfDoc = docEvent.getDocument();
            PdfPage page = docEvent.getPage();
            int pageNumber = pdfDoc.getPageNumber(page);

            PdfCanvas canvas = new PdfCanvas(page.newContentStreamBefore(), page.getResources(), pdfDoc);

            canvas.beginText().moveText(page.getPageSize().getWidth() / 2, page.getPageSize().getTop() - 35)
                    .setFontAndSize(PdfFontFactory.createFont(FontConstants.TIMES_ROMAN), 10)
                    .showText("Number of page " + pageNumber)
                    .endText();

            int table = getTable(pageNumber);
            if (-1 != table) {
                canvas.beginText().moveText(20, page.getPageSize().getTop() - 20)
                        .setFontAndSize(PdfFontFactory.createFont(FontConstants.TIMES_ROMAN), 10)
                        .showText("Table:" + table)
                        .endText();
            }

            canvas.release();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    class PageSpan {
        private int tableNum;
        private int lastPage;

        public PageSpan(int tableNum, int lastPage) {
            this.tableNum = tableNum;
            this.lastPage = lastPage;
        }

        public int getTableNum() {
            return tableNum;
        }

        public int getLastPage() {
            return lastPage;
        }
    }

}

现在唯一剩下的问题是如何使用这样的处理程序。答案是:

>

  • 在创建文档时立即将其添加到文档中。你不再需要移除处理程序:所有的事情都将由唯一的处理程序来完成;

    在向文档中添加表格之前,调用addTable,用一些不切实际的大数字指定最后一页。一个人不知道布局一个表格需要多少页,所以他应该确保即使是一个很长的表格也会被正确处理;

    一旦添加了一个表,就可以指定表的正确最后一页(在映射中,旧的一对将被重写)。

         PdfDocument pdfDoc = new PdfDocument(new PdfWriter(outFileName));
     Document doc = new Document(pdfDoc);
     TabPageHandler handler = new TabPageHandler();
     pdfDoc.addEventHandler(PdfDocumentEvent.END_PAGE, handler);
     for (int i = 1; i < 5; i++) {
         int firstPage = Math.max(1, doc.getPdfDocument().getNumberOfPages());
         Table table = new Table(UnitValue.createPercentArray(1)).useAllAvailableWidth();
         table.addHeaderCell(new Paragraph(i + ""));
         for (int j = 0; j < 40 * i; j++) {
             table.addCell(new Paragraph("aaa"));
         }
         handler.addTable(i, firstPage, 10000000);
         doc.add(table);
         int lastPage = doc.getPdfDocument().getNumberOfPages();
         handler.addTable(i, firstPage, lastPage);
         doc.add(new AreaBreak(AreaBreakType.NEXT_PAGE));
     }
     doc.close();
    

  •  类似资料:
    • 我的目标是添加一个自定义登录页面,以避免对Spring批处理管理控制台进行未经授权的访问。我设置了以下配置:

    • 我正在寻找禁用特定页面的手势。我遇到了许多帖子,建议将MasterDetailPage的设置为false以禁用它。这有效,但出于某种原因并不总是如此。 目前我只想在登录页面禁用手势,所以在身份验证时我启用手势,在出现时我禁用。 我遇到的问题是,如果用户切换应用程序并返回并退出,手势仍然启用。这让我认为正在触发不同的MasterDetailePage上下文。 有没有人遇到过这个问题,或者对我有什么指

    • 我正试着从一个特定的日期开始做一个计数计时器。我使用了这个(http://tutorialzine.com/2012/09/count-up-jquery/)教程来做,但我不知道在哪里放进去: $('#countdown').countup({start:new Date(2012,10,27,15,58,21)//年,月,日,小时,分钟,秒}); 就像描述中说的。 代码的开头看起来是这样的:

    • 问题内容: 在我的HTML页面上,我希望能够“转到” /“滚动到” /“关注”页面上的元素。 通常,我会使用带有的锚标记,但是我已经在使用hashchange事件和BBQ插件来加载此页面。 那么,是否还有其他方法可以通过JavaScript使页面转到页面上的给定元素? 这是我要执行的操作的基本概述: 问题答案: 插件形式的标准技术如下所示: 然后,您可以说滚动到。选件处理和可配置性留给读者练习。

    • 我从这个链接(Mifare Ultralight C Lock)获得了参考,使Mifare Ultralight标签上的所有页面都是只读的。 我可以在Android上成功地在Mi的Ultralight标签上写入消息。现在我想锁定第4到7页(或任何特定页面)。上面的链接只显示了如何锁定所有页面。我如何锁定特定页面? 此代码锁定所有页面:

    • 问题内容: 我有一个模板,显示作者可以编辑/删除的各种条目。用户可以单击“删除”来删除其帖子 删除后,用户将被重定向到条目页面,但该项目仍然存在,因此需要再次重新加载页面以显示删除效果。如果我禁用缓存,问题就会消失,但是我真的很想在所有其他页面中都拥有缓存… 添加这些标签无效,我认为我的浏览器只会忽略它们 我启用缓存槽: 有什么方法可以针对特定页面禁用它吗? 编辑 如建议,我尝试使用包装器: 并将