简体   繁体   中英

How to dynamically link bookmarks to table of contents using PDFsharp + MigraDoc

I'm trying to create a Table of Contents using MigraDoc and PDFsharp and I've gotten really close but the problem I'm currently having is that the links on the Table of Contents all take me to the very first page of the PDF. I'm trying to link them to their respective pages. PDFSharp bookmarks work fine but when trying to create a table of contents based on the merged PDF it's not working.

static void TableOfContents(PdfDocument document)
{
    // Puts the Table of contents on the second page
    PdfPage page = document.Pages[1];
    XGraphics gfx = XGraphics.FromPdfPage(page);
    gfx.MUH = PdfFontEncoding.Unicode;

    // Create MigraDoc document + Setup styles
    Document doc = new Document();
    Styles.DefineStyles(doc);

    // Add header
    Section section = doc.AddSection();
    Paragraph paragraph = section.AddParagraph("Table of Contents");
    paragraph.Format.Font.Size = 14;
    paragraph.Format.Font.Bold = true;
    paragraph.Format.SpaceAfter = 24;
    paragraph.Format.OutlineLevel = OutlineLevel.Level1;


    // Add links - these are the PdfSharp outlines/bookmarks
    // added previously when concatinating the pages
    foreach (var bookmark in document.Outlines)
    {
        paragraph = section.AddParagraph();
        paragraph.Style = "TOC";
        paragraph.AddBookmark(bookmark.Title);
        Hyperlink hyperlink = paragraph.AddHyperlink(bookmark.Title);
        hyperlink.AddText($"{bookmark.Title}\t");
        hyperlink.AddPageRefField(bookmark.Title);
    }

    // Render document
    DocumentRenderer docRenderer = new DocumentRenderer(doc);
    docRenderer.PrepareDocument();
    docRenderer.RenderPage(gfx, 1);
    gfx.Dispose();
}

Ideally I want it to return the file's name (which it's doing) and the page number (it's only returning the first page). This is what it's currently outputting.

Table of Contents
file name here......................... 1
file name here......................... 1
file name here......................... 1
file name here......................... 1

You invoke hyperlink.AddPageRefField to set a reference, but as far as I can tell you never create the MigraDoc bookmark for the target of the reference by calling MigraDoc's AddBookmark method.

MigraDoc bookmarks are different from PDF file bookmarks.

As I understand it, the Hyperlink and bookmark should be unique to the document. Otherwise the link will be made to the first paragraph containing the bookmark.

I simply use a number which I increase for a simple report I make.

 private void DefineTOCLine(int level, string text, Paragraph linkTo)
 {
     var tocIndex = (tocindex++).ToString(CultureInfo.InvariantCulture);

     var paragraph = tocsection.AddParagraph();
     paragraph.Style = level == 1 ? "TOC1" : "TOC2";
     var hyperlink = paragraph.AddHyperlink(tocIndex);
     hyperlink.AddText(text + "\t");
     hyperlink.AddPageRefField(tocIndex);

     linkTo.AddBookmark(tocIndex);
 }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM