简体   繁体   English

如何使用PDFsharp + MigraDoc将书签动态链接到目录

[英]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. 我正在尝试使用MigraDoc和PDFsharp创建目录,我已经非常接近,但我目前遇到的问题是目录中的链接都将我带到了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. PDFSharp书签工作正常,但在尝试根据合并的PDF创建目录时,它无法正常工作。

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 文件名在这里......................... 1
file name here......................... 1 文件名在这里......................... 1
file name here......................... 1 文件名在这里......................... 1
file name here......................... 1 文件名在这里......................... 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. 你调用的是hyperlink.AddPageRefField来设置引用,但据我所知,你永远不会通过调用MigraDoc的AddBookmark方法为引用的目标创建MigraDoc书签。

MigraDoc bookmarks are different from PDF file bookmarks. MigraDoc书签与PDF文件书签不同。

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);
 }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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