C# iText7目录

C# iText7目录,c#,.net,itext7,tableofcontents,C#,.net,Itext7,Tableofcontents,我是iText7新手,但对大多数概念都有相当好的理解 我想为我的PDF创建一个目录(TOC),并在他们的网站上找到以下java示例: 将程序转换为c#已经在普通文本中成功了,但是当将段落放在表格的单元格中时,它就不再有效了 此外,我无法让重新排序页面部分工作,有什么想法吗 编辑:找到了重新排序页面的方法 using iText.IO.Font.Constants; using iText.IO.Source; using iText.Kernel.Font; using iText.Kerne

我是iText7新手,但对大多数概念都有相当好的理解

我想为我的PDF创建一个目录(TOC),并在他们的网站上找到以下java示例:

将程序转换为c#已经在普通文本中成功了,但是当将段落放在表格的单元格中时,它就不再有效了

此外,我无法让重新排序页面部分工作,有什么想法吗

编辑:找到了重新排序页面的方法

using iText.IO.Font.Constants;
using iText.IO.Source;
using iText.Kernel.Font;
using iText.Kernel.Pdf;
using iText.Kernel.Pdf.Action;
using iText.Kernel.Pdf.Canvas.Draw;
using iText.Kernel.Pdf.Navigation;
using iText.Layout;
using iText.Layout.Element;
using iText.Layout.Hyphenation;
using iText.Layout.Layout;
using iText.Layout.Properties;
using iText.Layout.Renderer;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace ConsoleApp2
{
    class Program
    {
        public const string Src = @"C:\Users\mgs\source\repos\ConsoleApp2\text.txt";
        public const string Dest = @"C:\Users\mgs\source\repos\ConsoleApp2\table_of_contents.pdf";

        static void Main(string[] args)
        {
            byte[] bytes = CreatePdf();

            File.WriteAllBytes(Dest, bytes);
        }


        public static byte[] CreatePdf()
        {
            using (var s = new MemoryStream())
            {
                PdfDocument pdf = new PdfDocument(new PdfWriter(s));
                pdf.GetCatalog().SetPageMode(PdfName.UseOutlines);

                PdfFont font = PdfFontFactory.CreateFont(StandardFonts.TIMES_ROMAN);
                PdfFont bold = PdfFontFactory.CreateFont(StandardFonts.HELVETICA_BOLD);
                Document document = new Document(pdf);
                document.SetTextAlignment(TextAlignment.JUSTIFIED)
                        .SetHyphenation(new HyphenationConfig("en", "uk", 3, 3))
                        .SetFont(font)
                        .SetFontSize(11);

                // parse text to PDF
                Dictionary<string, KeyValuePair<string, int>> toc = WritePdf(pdf, bold, document);

                document.Add(new AreaBreak(AreaBreakType.NEXT_PAGE));

                // create table of contents
                int startToc = CreateToc(pdf, bold, document, toc);

                int tocPages = pdf.GetNumberOfPages() - startToc;

                document.Close();

                PdfDocument srcDoc = new PdfDocument(new PdfReader(new RandomAccessSourceFactory().CreateSource(s.ToArray()), new ReaderProperties()));

                using (MemoryStream ms = new MemoryStream())
                {
                    PdfDocument resultDoc = new PdfDocument(new PdfWriter(ms));
                    resultDoc.InitializeOutlines();


                    var pages = ReorderPages(tocPages, srcDoc, startToc);


                    srcDoc.CopyPagesTo(pages, resultDoc);

                    resultDoc.Close();
                    srcDoc.Close();

                    byte[] bytes = ms.ToArray();
                    return bytes;

                }
            }
        }

        private static List<int> ReorderPages(int tocPages, PdfDocument pdf, int startToc)
        {
            int allpages = pdf.GetNumberOfPages();

            var pages = new List<int>();
            for (var i = 0; i <= tocPages; i++)
            {
                pages.Add(startToc + i);
            }

            for (var i = 0; i < allpages - (tocPages + 1); i++)
            {
                pages.Add(i + 1);
            }

            return pages;
        }

        private static int CreateToc(PdfDocument pdf, PdfFont bold, Document document, Dictionary<string, KeyValuePair<string, int>> toc)
        {
            int startToc = pdf.GetNumberOfPages();
            var p = new Paragraph()
                .SetFont(bold)
                .Add("Table of Contents")
                .SetDestination("toc");

            document.Add(p);

            toc.Remove(toc.First().Key);
            List<TabStop> tabstops = new List<TabStop>();
            tabstops.Add(new TabStop(580, TabAlignment.RIGHT, new DottedLine()));

            foreach (KeyValuePair<string, KeyValuePair<string, int>> entry in toc)
            {
                KeyValuePair<string, int> text = entry.Value;
                string entryKey = entry.Key;
                string textKey = text.Key;
                string textValue = text.Value.ToString();

                p = new Paragraph()
                    .AddTabStops(tabstops)
                    .Add(textKey)
                    .Add(new Tab())
                    .Add(textValue)
                    .SetAction(PdfAction.CreateGoTo(entryKey));

                document.Add(p);
            }

            return startToc;
        }

        private static Dictionary<string, KeyValuePair<string, int>> WritePdf(PdfDocument pdf, PdfFont bold, Document document)
        {
            string[] lines = File.ReadAllLines(Src);
            var title = true;
            var counter = 0;
            PdfOutline outline = null;
            var toc = new Dictionary<string, KeyValuePair<string, int>>();

            var t = new Table(1);

            foreach (string line in lines)
            {
                var p = new Paragraph(line);
                p.SetKeepTogether(true);
                if (title)
                {
                    string name = "title" + counter++;
                    outline = CreateOutline(outline, pdf, line, name);

                    KeyValuePair<string, int> titlePage = new KeyValuePair<string, int>(line, pdf.GetNumberOfPages());
                    p.SetFont(bold)
                        .SetFontSize(12)
                        .SetKeepWithNext(true)
                        .SetDestination(name)
                        .SetNextRenderer(new UpdatePageRenderer(p, titlePage));

                    title = false;

                    //TODO: 
                    var c = new Cell().Add(p);
                    t.AddCell(c);

                    //document.Add(p);

                    toc.Add(name, titlePage);
                }
                else
                {
                    p.SetFirstLineIndent(36);
                    if (string.IsNullOrWhiteSpace(line))
                    {
                        p.SetMarginBottom(12);
                        title = true;
                    }
                    else
                    {
                        p.SetMarginBottom(0);
                    }

                    //TODO: 
                    var c = new Cell().Add(p);
                    t.AddCell(c);

                    //document.Add(p);
                }
            }

            //TODO: 
            document.Add(t);

            return toc;
        }

        protected class UpdatePageRenderer : ParagraphRenderer
        {
            protected KeyValuePair<string, int> Entry;

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

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

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

        public static PdfOutline CreateOutline(PdfOutline outline, PdfDocument pdf, String title, String name)
        {
            if (outline == null)
            {
                outline = pdf.GetOutlines(false);
                outline = outline.AddOutline(title);
                outline.AddDestination(PdfDestination.MakeDestination(new PdfString(name)));
                return outline;
            }
            var kid = outline.AddOutline(title);
            kid.AddDestination(PdfDestination.MakeDestination(newPdfString(name)));
            return outline;
        }
    }
}
使用iText.IO.Font.Constants;
使用iText.IO.Source;
使用iText.Kernel.Font;
使用iText.Kernel.Pdf;
使用iText.Kernel.Pdf.Action;
使用iText.Kernel.Pdf.Canvas.Draw;
使用iText.Kernel.Pdf.Navigation;
使用iText.Layout;
使用iText.Layout.Element;
使用iText.Layout.Hyphenation;
使用iText.Layout.Layout;
使用iText.Layout.Properties;
使用iText.Layout.Renderer;
使用制度;
使用System.Collections.Generic;
使用System.IO;
使用System.Linq;
名称空间控制台EApp2
{
班级计划
{
public const string Src=@“C:\Users\mgs\source\repos\ConsoleApp2\text.txt”;
public const string Dest=@“C:\Users\mgs\source\repos\ConsoleApp2\table\u of_contents.pdf”;
静态void Main(字符串[]参数)
{
byte[]bytes=CreatePdf();
File.writealBytes(Dest,字节);
}
公共静态字节[]CreatePdf()
{
使用(var s=new MemoryStream())
{
PdfDocument pdf=新PdfDocument(新PdfWriter);
pdf.GetCatalog().SetPageMode(PdfName.UseOutlines);
PdfFont font=PdfFontFactory.CreateFont(StandardFonts.TIMES_ROMAN);
PdfFont bold=PdfFontFactory.CreateFont(StandardFonts.HELVETICA_bold);
文件=新文件(pdf);
document.SetTextAlignment(TextAlignment.justized)
.SetHyphenation(新的HyphenationConfig(“en”,“uk”,3,3))
.SetFont(字体)
.SetFontSize(11);
//将文本解析为PDF
字典toc=WritePdf(pdf,粗体,文档);
添加(新的AreaBreak(AreaBreakType.NEXT_PAGE));
//创建目录
int startToc=CreateToc(pdf,粗体,文档,toc);
int tocPages=pdf.GetNumberOfPages()-startToc;
document.Close();
PdfDocument srcDoc=新的PdfDocument(新的PDF阅读器(新的RandomAccessSourceFactory().CreateSource(s.ToArray()),新的ReaderProperties());
使用(MemoryStream ms=new MemoryStream())
{
PdfDocument resultDoc=新PdfDocument(新PdfWriter(ms));
resultDoc.InitializeOutlines();
var pages=重新订购页(tocPages、srcDoc、startToc);
srcDoc.CopyPagesTo(第页,结果DC);
resultDoc.Close();
srcDoc.Close();
byte[]bytes=ms.ToArray();
返回字节;
}
}
}
私有静态列表重新排序页(int-tocPages、PdfDocument-pdf、int-startToc)
{
int allpages=pdf.GetNumberOfPages();
var pages=新列表();

对于(var i=0;i而言,所有页码都是
0
的原因是,在尝试获取页码之前,您没有添加任何内容

突出显示
WritePdf()
函数的重要部分:

private static Dictionary < string, KeyValuePair < string, int >> WritePdf(PdfDocument pdf, PdfFont bold, Document document) {

  ...
  var t = new Table(1);

  ...
  foreach (string line in lines) {
   //Adding content to the table and getting the page numbers. 
    //Content is *not* added to the document yet, so pdf.GetNumberOfPages() returns 0
  }

  ...
  document.add(t); //Finally adding the table to the document after it is too late

}
private static Dictionary<string, KeyValuePair<string, int>> WritePdf(PdfDocument pdf, PdfFont bold, Document document)
    {
        string[] lines = File.ReadAllLines(SRC);
        var title = true;
        var counter = 0;
        PdfOutline outline = null;
        var toc = new Dictionary<string, KeyValuePair<string, int>>();

        var t = new Table(1, true);

        document.Add(t);

            foreach (string line in lines) {
            var p = new Paragraph(line);
            p.SetKeepTogether(true);
            if (title) {
                string name = "title" + counter++;
                outline = CreateOutline(outline, pdf, line, name);

                KeyValuePair<string, int> titlePage = new KeyValuePair<string, int>(line, pdf.GetNumberOfPages());
                p.SetFont(bold)
                    .SetFontSize(12)
                    .SetKeepWithNext(true)
                    .SetDestination(name)
                    .SetNextRenderer(new UpdatePageRenderer(p, titlePage));

                title = false;

                //TODO: 

                //document.Add(p);

                toc.Add(name, titlePage);
            }
            else {
                p.SetFirstLineIndent(36);
                if (string.IsNullOrWhiteSpace(line)) {
                    p.SetMarginBottom(12);
                    title = true;
                }
                else {
                    p.SetMarginBottom(0);
                }

                //TODO: 
                var c = new Cell().Add(p);
                t.AddCell(c);

                //document.Add(p);
            }
                t.Flush();
        }
            t.Complete();

        //TODO: 


        return toc;
    }
private static Dictionary>WritePdf(PdfDocument pdf,PdfFont bold,Document文档){
...
var t=新表(1);
...
foreach(行中的字符串行){
//向表中添加内容并获取页码。
//内容*尚未*添加到文档中,因此pdf.GetNumberOfPages()返回0
}
...
document.add(t);//太晚了,最后才将表添加到文档中
}
您可以先将表添加到文档中,然后定期刷新它,从而稍微改变方法:

private static Dictionary < string, KeyValuePair < string, int >> WritePdf(PdfDocument pdf, PdfFont bold, Document document) {

  ...
  var t = new Table(1, true); //True stands for "large table" which allows us to flush the content.
  document.Add(t); //Immediately add the document to the table

  ...
  foreach (string line in lines) {

    //Add whatever you want to the table

    t.flush(); //But make sure to flush the content so the page numbers are correct
  }

  ...
  t.complete() //Tell the renderer that the table will not have any more content added to it.

}
private static Dictionary>WritePdf(PdfDocument pdf,PdfFont bold,Document文档){
...
var t=new Table(1,true);//true代表“大表”,它允许我们刷新内容。
document.Add(t);//立即将文档添加到表中
...
foreach(行中的字符串行){
//在表中添加您想要的内容
t、 flush();//但请确保刷新内容,以便页码正确
}
...
t、 complete()//告诉呈现程序该表将不再添加任何内容。
}
这将是您的更新功能:

private static Dictionary < string, KeyValuePair < string, int >> WritePdf(PdfDocument pdf, PdfFont bold, Document document) {

  ...
  var t = new Table(1);

  ...
  foreach (string line in lines) {
   //Adding content to the table and getting the page numbers. 
    //Content is *not* added to the document yet, so pdf.GetNumberOfPages() returns 0
  }

  ...
  document.add(t); //Finally adding the table to the document after it is too late

}
private static Dictionary<string, KeyValuePair<string, int>> WritePdf(PdfDocument pdf, PdfFont bold, Document document)
    {
        string[] lines = File.ReadAllLines(SRC);
        var title = true;
        var counter = 0;
        PdfOutline outline = null;
        var toc = new Dictionary<string, KeyValuePair<string, int>>();

        var t = new Table(1, true);

        document.Add(t);

            foreach (string line in lines) {
            var p = new Paragraph(line);
            p.SetKeepTogether(true);
            if (title) {
                string name = "title" + counter++;
                outline = CreateOutline(outline, pdf, line, name);

                KeyValuePair<string, int> titlePage = new KeyValuePair<string, int>(line, pdf.GetNumberOfPages());
                p.SetFont(bold)
                    .SetFontSize(12)
                    .SetKeepWithNext(true)
                    .SetDestination(name)
                    .SetNextRenderer(new UpdatePageRenderer(p, titlePage));

                title = false;

                //TODO: 

                //document.Add(p);

                toc.Add(name, titlePage);
            }
            else {
                p.SetFirstLineIndent(36);
                if (string.IsNullOrWhiteSpace(line)) {
                    p.SetMarginBottom(12);
                    title = true;
                }
                else {
                    p.SetMarginBottom(0);
                }

                //TODO: 
                var c = new Cell().Add(p);
                t.AddCell(c);

                //document.Add(p);
            }
                t.Flush();
        }
            t.Complete();

        //TODO: 


        return toc;
    }
private static Dictionary WritePdf(PdfDocument pdf,PdfFont bold,Document文档)
{
string[]lines=File.ReadAllLines(SRC);
var title=true;
var计数器=0;
PdfOutline outline=null;
var toc=新字典();
var t=新表(1,真);
文件.添加(t);
foreach(行中的字符串行){
var p=新段落(行);
p、 SetKeepTogether(真);
如果(标题){
string name=“title”+计数器++;
outline=CreateOutline(大纲、pdf、行、名称);
KeyValuePair titlePage=新的KeyValuePair(第行,pdf.GetNumberOfPages());
p、 SetFont(粗体)
.SetFontSize(12)
.SetKeepWithNext(真)
.SetDestination(名称)
.SetNextRenderer(新的更新描述符(p,标题页));
标题=假;
//待办事项:
//文件.添加(p);
目录添加(名称、标题页);
}
否则{
p、 SetFirstLineIndent(36);
if(string.IsNullOrWhiteSpace(行)){
p、 SetMarginBottom(12);