【问题标题】:How to Define a PDF Outline Using MigraDoc如何使用 MigraDoc 定义 PDF 大纲
【发布时间】:2015-04-07 01:07:07
【问题描述】:

我注意到在使用 MigraDoc 时,如果我添加带有任何标题样式的段落(例如,“Heading1”),则会在文档大纲中自动放置一个条目。我的问题是,如何在文档大纲中添加条目而不显示文档中的文本?这是我的代码示例:

var document = new Document();
var section = document.AddSection();
// The following line adds an entry to the document outline, but it also
//     adds a line of text to the current section.  How can I add an
//     entry to the document outline without adding any text to the page?
var paragraph = section.AddParagraph("TOC Level 1", "Heading1");

【问题讨论】:

    标签: c# pdfsharp migradoc


    【解决方案1】:

    我使用了一个技巧:在白底上添加白色文本,字体大小为 0.001 左右,以获得用户实际上不可见的轮廓。

    要获得完美的解决方案,请混合使用 PDFsharp 和 MigraDoc 代码。 hack 对我有用,而且更容易实现。

    【讨论】:

    • 您的回答启发了我使用混合 PDFSharp/MigraDoc 方法。我在自己的答案中发布了最终使用的代码。
    【解决方案2】:

    在阅读 ThomasH 的回答后,我意识到我已经在混合 PDFSharp 和 MigraDoc 代码。由于我使用的是 PdfDocumentRenderer,因此我能够向该渲染器的 PdfDocument 属性添加自定义大纲。以下是我最终创建自定义大纲的示例:

    var document = new Document();
    // Populate the MigraDoc document here
    ...
    
    // Render the document
    var renderer = new PdfDocumentRenderer(false, PdfFontEmbedding.Always)
    {
        Document = document
    };
    renderer.RenderDocument();
    
    // Create the custom outline
    var pdfSharpDoc = renderer.PdfDocument;
    var rootEntry = pdfSharpDoc.Outlines.Add(
        "Level 1 Header", pdfSharpDoc.Pages[0]);
    rootEntry.Outlines.Add("Level 2 Header", pdfSharpDoc.Pages[1]);
    
    // Etc.
    
    // Save the document
    pdfSharpDoc.Save(outputStream);
    

    【讨论】:

      【解决方案3】:

      我有一个稍微少一点被黑的方法。下面是基本方法:

      1) 添加书签,将书签字段对象和大纲条目的名称保存到列表中。不要设置段落.OutlineLevel(或设置为正文)

      // Defined previously
      List<dynamic> Bookmarks = new List<dynamic>();
      
      // In your bookmarking method, P is a Paragraph already created somewhere
      Bookmarks.Add(new { Bookmark = P.AddBookmark("C1"), Name = "Chapter 1", Depth = 0 });
      

      2) 在 Migradoc 布局结束时,在渲染之前,准备页面

      pdfwriter.PrepareRenderPages();
      

      3) 建立书签的父级(这将是一个段落)和页面(页面将被初始化为-1)的字典

      var Pages = Bookmarks.Select(x=> ((BookmarkField)x).Bookmark.Parent.Parent).ToDictionary(x=>x, x=>-1);
      

      4) 现在通过遍历每个页面上的对象来填充这些页面,找到匹配项

      for (int i = 0; i < pdfwriter.PageCount; i++)
          foreach (var s in pdfwriter.DocumentRenderer.GetDocumentObjectsFromPage(i).Where(x=> Pages.ContainsKey(x))
              Pages[s] = i-1;
      

      5) 您现在已经有了 Bookmark 的父母的父母到页码的字典,您可以将大纲直接添加到 PDFSharp 文档中。这也会向下迭代深度树,因此您可以嵌套轮廓

      foreach(dynamic d in Bookmarks)
      {
          var o = pdfwriter.PdfDocument.Outlines;
          for(int i=0;i<d.Depth;i++)
              o = o.Last().Outlines;
          BookmarkField BK = d.Bookmark;
          int PageNumber = Pages[BK.Parent.Parent];
          o.Add(d.Name, pdfwriter.PdfDocument.Pages[PageNumber], true, PdfOutlineStyle.Regular);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-04-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多