如何使用MigraDoc定义PDF大纲

4

我注意到在使用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");
3个回答

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

2

我有一种比较不那么"hack"的方法。以下是基本步骤:

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

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

在渲染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) 现在您已经获得了一个书签父母的父母到页码的字典,通过这个字典,您可以直接将大纲添加到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);
}

2

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

对于完美的解决方案,请混合使用PDFsharp和MigraDoc代码。这种技巧对我很有效,而且更容易实现。


1
你的回答启发了我尝试使用混合的PDFSharp/MigraDoc方法。我在我的回答中发布了我最终使用的代码。 - Jeff G

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接