如何用c#在itext7的标题页中添加目录?

问题描述 投票:0回答:1

我想在标题页的

Cell
中插入目录。我需要先生成内容,然后才能知道目录的数据是什么。但是,当我向单元格添加内容时,它在渲染的 Pdf 中保持空白。

我生成包含

Cell tocArea
中的
GenerateTitlePage()
的标题页,填充
toc
中的列表
GenerateContentPages()
,然后尝试填充
tocArea
中的
FillTOC()

namespace ProductTest
{
    internal class ProductDocument
    {
        // class variables omitted

        List<KeyValuePair<string, KeyValuePair<string, int>>> toc = new List<KeyValuePair<string, KeyValuePair<string, int>>>();

        public void CreatePdf()
        {
            // general setup
            string filename = "ProductTest.pdf";

            PdfDocument bgPdf = new PdfDocument(new PdfReader(templateLocation));
            PdfPage bgPage = bgPdf.GetPage(1);

            PageSize pageSize = PageSize.A4.Rotate();

            PdfDocument pdf = new PdfDocument(new PdfWriter(filename));
            pdf.AddEventHandler(PdfDocumentEvent.END_PAGE, new HeaderFooterEventHandler(pdf));

            Document doc = new Document(pdf, pageSize, false);
            DocumentRenderer renderer = new DocumentRenderer(doc, false);
            doc.SetRenderer(renderer);

            doc.SetMargins(40, 6, 30, 6);

            Cell tocArea = new Cell().SetBorder(null);

            CreateTitlePage(doc, pageSize, bgPage, tocArea);

            CreateContentPages(doc, pageSize);

            FillTOC(doc, tocArea);

            bgPdf.Close();
            doc.Close();

            Process.Start(new ProcessStartInfo(filename) { UseShellExecute = true });
        }

        private void CreateContentPages(Document doc, PageSize pageSize)
        {
           PdfDocument pdf = doc.GetPdfDocument();
           PdfPage page = pdf.AddNewPage(pageSize);
           
           // set up columns
           float horizontalOffset = 20;
           float verticalOffset = 60;
           float gap = 50;
           float columnWidth = (pageSize.GetWidth() - 2 * horizontalOffset - gap) / 2;
           float columnHeight = pageSize.GetHeight() - 2 * verticalOffset;

           Rectangle[] columns = new Rectangle[]
           {
               new Rectangle(horizontalOffset, verticalOffset, columnWidth, columnHeight),
               new Rectangle(horizontalOffset + columnWidth + gap, verticalOffset, columnWidth, columnHeight)
           };

           doc.SetRenderer(new ColumnDocumentRenderer(doc, false, columns));
           doc.Add(new AreaBreak(AreaBreakType.LAST_PAGE));

           // Content is created here and toc populated
           // omitted for brevity
        }

        private void CreateTitlePage(Document doc, PageSize pageSize, PdfPage bgPage, Cell tocArea)
        {
            PdfDocument pdf = doc.GetPdfDocument();
            PdfPage page = pdf.AddNewPage(pageSize);
            Rectangle orig = bgPage.GetPageSizeWithRotation();
            doc.SetRenderer(new DocumentRenderer(doc));
            doc.Add(new AreaBreak(AreaBreakType.LAST_PAGE));

            // copy bg template
            PdfCanvas canvas = new PdfCanvas(page);
            AffineTransform transformationMatrix = AffineTransform.GetScaleInstance(page.GetPageSize().GetWidth() / orig.GetWidth(), page.GetPageSize().GetHeight() / orig.GetHeight());
            canvas.ConcatMatrix(transformationMatrix);
            PdfFormXObject pageCopy = bgPage.CopyAsFormXObject(pdf);
            canvas.AddXObjectAt(pageCopy, 0, 0);

            // title page layout
            float infBoxWidth = 184;
            float titleContentWidth = page.GetPageSize().GetWidth() - doc.GetLeftMargin() - doc.GetRightMargin() - infBoxWidth;

            Table layout = new Table(new float[] { titleContentWidth, infBoxWidth });
            layout.SetWidth(UnitValue.CreatePercentValue(100))
                .AddCell(new Cell())
                .AddCell(new Cell())
                .SetMargins(24, 0, 0, 0);

            // left column
           // omitted for brevity
            headingText = "Content / Appendix";
            outline = CreateOutline(outline, pdf, headingText, headingText);
            leftColumn.Add(new Paragraph(headingText).AddStyle(heading2).SetDestination(headingText));

            // I add my placeholder cell here
            Table table = new Table(1).SetWidth(UnitValue.CreatePercentValue(100)).SetMarginLeft(20).AddCell(tocArea);
            leftColumn.Add(table);

            // info box in right column
            // omitted for brevity

            doc.Add(layout);
        }

        // Here I try to fill the TOC with data. I get no errors, the cell is just blank in the rendered pdf
        private void FillTOC(Document doc, Cell tocArea)
        {
            // create table of contents
            int counter = 0;
            List<TabStop> tabStops = new List<TabStop>();
            DottedLine dottedLine = new DottedLine(1, 3);
            dottedLine.SetColor(ColorConstants.BLUE);
            tabStops.Add(new TabStop(600, TabAlignment.RIGHT, dottedLine));
            foreach (KeyValuePair<string, KeyValuePair<string, int>> entry in toc)
            {
                KeyValuePair<string, int> text = entry.Value;
                Paragraph paragraph = new Paragraph()
                    .SetFont(arial)
                    .SetFontSize(9)
                    .SetFontColor(ColorConstants.BLUE)
                    .SetTextAlignment(TextAlignment.JUSTIFIED)
                    .AddTabStops(tabStops)
                    .Add($"{++counter:d2} " + text.Key)
                    .Add(new Tab())
                    .Add(text.Value.ToString())
                    .SetAction(PdfAction.CreateGoTo(entry.Key));
                tocArea.Add(paragraph);
            }
            
        }

        // adds bookmarks to document
        private PdfOutline CreateOutline(PdfOutline outline, PdfDocument pdf, String title, String name)
        {
            // ommitted for brevity
        }

        // adds header and page number to pages
        private class HeaderFooterEventHandler : IEventHandler
        {
            // ommitted for brevity
        }
    }
}

c# pdf itext itext7
1个回答
0
投票

因此,如果有人感兴趣,建议的工作流程是:

  1. 正常创建PDF。 (在这种情况下我排除了扉页)
  2. 使用此 Stack Overflow 示例中的以下示例计算出页码:从文档大纲(书签)中获取页码
  3. 将这些页码存储在某处
  4. 只有这一次创建另一个 PDF 文档,您才会知道您创建的第一个 PDF 的轮廓页码。 (由于步骤 1,我在页码中添加了 +1 以占标题页)
© www.soinside.com 2019 - 2024. All rights reserved.