itext 7 table 的内容问题

itext 7 table of contents issues

遵循本例中的模式https://kb.itextpdf.com/home/it7kb/examples/toc-as-first-page 我在自己的代码中实现了 table of contents (toc)。一切正常,但有以下例外:

此代码是概念验证。我有逻辑来确定目录中有多少页并将它们循环移动。

屏幕截图:

堆栈跟踪:

   at KernelExtensions.Get[TKey,TValue](IDictionary`2 col, TKey key)
   at iText.Kernel.Pdf.PdfDictionary.Put(PdfName key, PdfObject value)
   at iText.Kernel.Pdf.PdfPages.AddPage(Int32 index, PdfPage pdfPage)
   at iText.Kernel.Pdf.PdfPagesTree.AddPage(Int32 index, PdfPage pdfPage)
   at iText.Kernel.Pdf.PdfDocument.MovePage(Int32 pageNumber, Int32 insertBefore)
   at BlueCoatExtractor.PDFHelper.buildPDFNatively1(String header, String dtStamp, Dictionary`2 bcPoliciesDict, String dest) in C:\Users\xyz\source\repos\bbb\bbb\PDFHelper.cs:line 216

重现问题的完整示例代码:

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;

using iText.IO.Font.Constants;
using iText.Kernel.Font;
using iText.Kernel.Pdf;
using iText.Kernel.Pdf.Action;
using iText.Kernel.Pdf.Canvas.Draw;
using iText.Layout;
using iText.Layout.Element;
using iText.Layout.Hyphenation;
using iText.Layout.Layout;
using iText.Layout.Properties;
using iText.Layout.Renderer;
using iText.Kernel.Utils;

namespace BlueCoatExtractor
{
    public class C06E04_TOC_GoToNamed
    {
        public const String SRC = "Logs/jekyll_hyde.txt";

        public const String DEST = "Output/jekyll_hyde_toc2.pdf";

        internal static void initialize()
        {
            FileInfo file = new FileInfo(DEST);
            file.Directory.Create();
            //new C06E04_TOC_GoToNamed().CreatePdf(DEST);
        }

        public static void CreatePdf()
        {
            //Initialize PDF document
            PdfDocument pdf = new PdfDocument(new PdfWriter(DEST));
            // Initialize document
            Document document = new Document(pdf);
            PdfFont font = PdfFontFactory.CreateFont(StandardFonts.TIMES_ROMAN);
            PdfFont bold = PdfFontFactory.CreateFont(StandardFonts.HELVETICA_BOLD);
            document.SetTextAlignment(TextAlignment.JUSTIFIED).SetHyphenation(new HyphenationConfig("en", "uk", 3, 3))
                .SetFont(font).SetFontSize(11);
            StreamReader sr = File.OpenText(SRC);
            String name;
            String line;
            Paragraph p;
            bool title = true;
            int counter = 0;

            IList<KeyValuePair<String, KeyValuePair<String, int>>> toc = new List<KeyValuePair
                <String, KeyValuePair<String, int>>>();
            while ((line = sr.ReadLine()) != null)
            {
                p = new Paragraph(line);
                p.SetKeepTogether(true);
                if (title)
                {
                    name = String.Format("title{0:00}", counter++);
                    KeyValuePair<String, int> titlePage = new KeyValuePair<string, int>(line, pdf.GetNumberOfPages());
                    p.SetFont(bold).SetFontSize(12).SetKeepWithNext(true).SetDestination(name).SetNextRenderer(new UpdatePageRenderer(p, titlePage));
                    title = false;
                    document.Add(p);
                    toc.Add(new KeyValuePair<string, KeyValuePair<string, int>>(name, titlePage));
                }
                else
                {
                    p.SetFirstLineIndent(36);
                    if (String.IsNullOrEmpty(line))
                    {
                        p.SetMarginBottom(12);
                        title = true;
                    }
                    else
                    {
                        p.SetMarginBottom(0);
                    }
                    document.Add(p);
                }
            }
            document.Add(new AreaBreak(AreaBreakType.NEXT_PAGE));
            p = new Paragraph().SetFont(bold).Add("Table of Contents").SetDestination("toc");
            document.Add(p);
            toc.RemoveAt(0);
            IList<TabStop> tabstops = new List<TabStop>();
            tabstops.Add(new TabStop(580, TabAlignment.RIGHT, new DottedLine()));
            foreach (KeyValuePair<String, KeyValuePair<String, int>> entry in toc)
            {
                KeyValuePair<String, int> text = entry.Value;
                p = new Paragraph().AddTabStops(tabstops).Add(text.Key).Add(new Tab()).Add(text.Value.ToString()).SetAction
                    (PdfAction.CreateGoTo(entry.Key));
                document.Add(p);
            }
            //Close document

            int tocPageNumber = pdf.GetNumberOfPages();
            pdf.MovePage(tocPageNumber, 1);
            pdf.MovePage(tocPageNumber, 1);
            pdf.MovePage(tocPageNumber, 1); // null exception

            document.Close();
        }

        protected internal class UpdatePageRenderer : ParagraphRenderer
        {
            protected internal KeyValuePair<String, int> entry;

            public UpdatePageRenderer(Paragraph modelElement, KeyValuePair
                <String, int> entry)
                : base(modelElement)
            {
                this.entry = entry;
            }

            public override LayoutResult Layout(LayoutContext layoutContext)
            {
                LayoutResult result = base.Layout(layoutContext);
                int pageNumber = layoutContext.GetArea().GetPageNumber();
                entry = new KeyValuePair<string, int>(entry.Key, pageNumber);
                return result;
            }
        }
    }
}

使用以下文本文件:https://github.com/itext/i7js-highlevel/blob/develop/src/main/resources/txt/jekyll_hyde.txt

基于此代码中的模式:https://github.com/itext/i7ns-samples/blob/develop/itext/itext.samples/itext/samples/sandbox/stamper/ReorderPages.cs

我创建了一个新文档并将原文档的内容复制到其中。 table 内容链接仍按预期运行。

        fs = File.Create("Output/resultDoc.pdf");
        fs.Dispose();

        PdfDocument srcDoc = new PdfDocument(new PdfReader(dest));
        var srcTotalPages = srcDoc.GetNumberOfPages();

        PdfDocument resultDoc = new PdfDocument(new PdfWriter("Output/resultDoc.pdf"));
        resultDoc.InitializeOutlines();


        IList<int> pages = new List<int>();
        pages.Add(101);
        pages.Add(102);
        pages.Add(103);

        for (int i = 1; i <= 100; i++)
        {
            pages.Add(i);
        }

        srcDoc.CopyPagesTo(pages, resultDoc);

        resultDoc.Close();

        srcDoc.Close();