Как определить схему PDF с помощью MigraDoc

Я заметил, что при использовании MigraDoc, если я добавляю абзац с любым из стилей заголовка (например, "Заголовок1"), запись автоматически помещается в схему документа. У меня вопрос, как я могу добавить записи в структуре документа, не показывая текст в документе? Вот пример моего кода:

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 ответа

Решение

Прочитав ответ 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);

Я использовал хак: добавил белый текст на белом фоне с размером шрифта 0,001 или около того, чтобы получить контуры, которые фактически невидимы для пользователя.

Для идеального решения смешайте код PDFsharp и MigraDoc. Хак у меня работает и намного проще в реализации.

У меня есть метод, который немного менее взломан. Вот основной метод:

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

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);
}
Другие вопросы по тегам