Как определить схему 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);
}