首页 > 解决方案 > 将整个旧的 Lowagie PDF 生成器迁移到 iText 7 c#。创建目录

问题描述

由于在 API 的早期版本中存在 Anchor 对象,它应该作为文本中的链接工作,我正在尝试在许多教程中寻找一种添加 TOC 的方法,将您从索引重定向到标题所在的页面。

问题是我正在生成基于 XML 文档的 PDF,因此 TOC 会因 XML 内容而异。

我已经从 0 开始使用 iText7 for C# 并且感谢 itextpdf.com 上的教程和一些 stackOverflow 教程,在许多其他人之间,我已经能够制作几乎所有我想要的东西,除了这个。无论如何,我很困惑,因为我只找到旧的 iText5 引用或更旧的 iText7 java 引用,有时我无法“翻译”成 c# 等。

我尝试为包含标题和我想去的页面的单元格设置一个属性。

我还查看了一些谈论从文件中添加内容的地方。但是,这已经在我的代码中完成了,所以我应该直接处理字符串。甚至不是一个数组(或任何类似的),因为我将逐个字符串处理。

pe:我的程序从节点接收 XML 值“第 1 章”,并自动将其添加到字符串中。所以,我会在需要的段落和目录中添加这个字符串。

这样做是因为它是一个非常复杂的 XML 文件(例如,文件中有 848 行)。

Paragraph indice = new Paragraph(new Text("Here the TOC line"));
Paragraph title = new Paragraph(new Text("Here the title"));
/*This goes at page 20. I am making further investigation so as to locate how should I look for the page (Looking for the string at the doc and getting the page, for example)*/

indice.SetProperty(Property.ACTION, PdfAction.CreateGoToR(@"C:\aplic\pdfPruebasIText\pdfPruebasIText\docPrueba.pdf", 20));

(Document) docPDF.add(indice);//TOC goes first
//More content
docPDF.add(title);//What I want indexed

我正在我的 docPrueba.pdf 文档中添加更多文本、段落、表格等。刚刚添加了我认为是我的问题的主线。如有必要,我会添加更多行

理论上,它应该转到我的文档 docPrueba.pdf 的第 20 页实际上,它什么也不做,除了让鼠标指针改变它的形状。

没有显示错误消息,也没有任何错误。我添加的所有内容都生成了,除了这个失败。

标签: c#pdf-generationitext7

解决方案


基于此线程:iText7 目录

我编写了代码,以便在处理文档时可以向 TOC 添加行。

现在的主要问题是目录是在文档的末尾创建的(哎呀!)。所以我现在正在努力解决这个问题。

现在,我将在此处添加修改后的代码:

 string tit0 = "Titulo 0";//Title strings to add to a Dictionary
 string tit1 = "Titulo 1";
 string tit2 = "Titulo 2";

 Dictionary<string, KeyValuePair<string, int>> indiceRelaciones = new Dictionary<string, KeyValuePair<string, int>>();

 indiceRelaciones=EscribirIndicePDF(innerDoc, DocPDF, tit0, indiceRelaciones);//HERE the title is added to the document and the dictionary flushed
 DocPDF.Add(parrafo1);//Paragraphs, tables and stuff
 DocPDF.Add(tabla1);
 DocPDF.Add(tabla2);
 indiceRelaciones = EscribirIndicePDF(innerDoc, DocPDF, tit1, indiceRelaciones);
 DocPDF.Add(parrafo2);
 indiceRelaciones = EscribirIndicePDF(innerDoc, DocPDF, tit2, indiceRelaciones);
 DocPDF.Add(parrafo3);

 crearIndice(innerDoc, DocPDF, indiceRelaciones);//This method generates the TOC
 DocPDF.Close();




 private static Dictionary<string, KeyValuePair<string, int>> EscribirIndicePDF(PdfDocument innerDoc, Document docPDF, string tit, Dictionary<string, KeyValuePair<string, int>> indice)
    {
        Paragraph titulo = new Paragraph().Add(new Text(tit));
        titulo.SetKeepTogether(true);
        outline = CreateOutline(outline, innerDoc, tit);
        KeyValuePair<string, int> paginaTitulo = new KeyValuePair<string, int>(tit, innerDoc.GetNumberOfPages());
        titulo.SetFontColor(ColorConstants.BLUE).SetDestination(tit).SetKeepWithNext(true).SetNextRenderer(new UpdatePageRenderer(titulo, paginaTitulo));
        docPDF.Add(titulo);
        indice.Add(tit, paginaTitulo);
        return indice;
    }


private static void crearIndice(PdfDocument innerDoc, Document docPDF, Dictionary<string, KeyValuePair<string, int>> indiceRelaciones)
    {//¡Este método crea en la primera página el índice! Este no se toca. Se modifica el otro para que se llame y se agreguen entradas al diccionario.
        List<TabStop> tabStops = new List<TabStop>();
        tabStops.Add(new TabStop(580, TabAlignment.RIGHT, new DottedLine()));
        foreach (KeyValuePair<string, KeyValuePair<string, int>> entrada in indiceRelaciones) {
            KeyValuePair<string, int> texto = entrada.Value;
            string claveEntrada = entrada.Key;
            string claveTexto = texto.Key;
            string valorTexto = texto.Value.ToString();

            Paragraph p = new Paragraph().AddTabStops(tabStops).Add(claveTexto).Add(new Tab()).Add(valorTexto).SetAction(PdfAction.CreateGoTo(claveEntrada));
            docPDF.Add(p);
        }
    }


private static PdfOutline CreateOutline(PdfOutline outline, PdfDocument innerDoc, string line)
    {
        if (outline == null)
        {
            outline = innerDoc.GetOutlines(false);
            outline = outline.AddOutline(line);
            outline.AddDestination(PdfDestination.MakeDestination(new PdfString(line)));
            return outline;
        }

        PdfOutline hijo = outline.AddOutline(line);
        hijo.AddDestination(PdfDestination.MakeDestination(new PdfString(line)));
        return outline;
    }

    internal class UpdatePageRenderer : ParagraphRenderer
{
    private KeyValuePair<string, int> Entrada;

    public UpdatePageRenderer(Paragraph modelElement, KeyValuePair<string, int> entrada) : base(modelElement)
    {
        Entrada = entrada;
    }

    public override LayoutResult Layout(LayoutContext layoutContext)
    {
        LayoutResult result = base.Layout(layoutContext);
        int pagina = layoutContext.GetArea().GetPageNumber();

        Entrada = new KeyValuePair<string, int>(Entrada.Key, pagina);
        return result;
    }
}

我为使用西班牙名字道歉。我将编辑这篇文章以使用英文名称,以便每个人都能理解代码。

现在...

我将尝试在第一页获取目录(应该如此)


推荐阅读