【问题标题】:Create Multi-page Index File(TOC) for merged pdf using itext library in java在java中使用itext库为合并的pdf创建多页索引文件(TOC)
【发布时间】:2016-04-01 21:53:31
【问题描述】:

如何使用 iTextSharp 在包含合并文档的 PDF 末尾编写多页 ToC?

Create Index File(TOC) for merged pdf using itext library in java 的答案解释了如何在合并 PDF 时创建 ToC 页面(目录在 iTextSharp 书籍 http://developers.itextpdf.com/examples/merging-pdf-documents/merging-documents-and-create-table-contents#795-mergewithtoc.java 中)。此答案中的代码基于这些示例。

但是,它仅适用于 ToC 为 1 页长的情况。如果内容变长,则它会在同一页面上重复,而不是跨越到下一页。

尝试通过以下方式将链接直接添加到文本中:

ct.Add(new Chunk("link").SetLocalGoto("p1"))

导致异常(“无法添加注释,文档中的页面不足”)。

任何人都可以解释一种方法,该方法允许我在合并它们时将多页内容附加到 PDF 中(方法越通用越好)。有没有办法使用 Document.Add() 写入文档,而不必复制模板页面并在其顶部写入?

(注意,代码是c#)

【问题讨论】:

    标签: c# pdf itext


    【解决方案1】:

    此答案基于example from the iTextSharp documentation,但已转换为 C#。

    为了使添加的文本跨越多个页面,我发现我可以使用ColumnText.HasMoreText(ct.Go()) 告诉我是否有更多的文本超出了当前页面的容量。然后,您可以保存当前页面,重新创建新页面模板,并将列文本移动到新页面。下面是一个名为 CheckForNewPage 的函数:

        private bool CheckForNewPage(PdfCopy copy, ref PdfImportedPage page, ref PdfCopy.PageStamp stamp, ref PdfReader templateReader, ColumnText ct)
        {
            if (ColumnText.HasMoreText(ct.Go()))
            {
                //Write current page
                stamp.AlterContents();
                copy.AddPage(page);
    
                //Start a new page
                ct.SetSimpleColumn(36, 36, 559, 778);
                templateReader = new PdfReader("template.pdf");
                page = copy.GetImportedPage(templateReader, 1);
                stamp = copy.CreatePageStamp(page);
                ct.Canvas = stamp.GetOverContent();
                ct.Go();
                return true;
            }
            return false;
        }
    

    应该在每次将文本添加到 ct 变量时调用它。

    如果 CheckForNewPage 返回 true,您可以增加页数,并将 y 变量重置为新页面的顶部,以便链接注释位于新页面上的正确位置。

    例如

    var tocPageCount = 0;
    
    
    var para = new iTextSharp.text.Paragraph(documentName);
    ct.AddElement(para);
    ct.Go();
    if (CheckForNewPage(context, copy, ref page, ref stamp, ref tocReader, ct))
    {
        tocPageCount++;
        y = 778;
    }
    
    //Add link annotation
    action = PdfAction.GotoLocalPage(d.DocumentID.ToString(), false);
    link = new PdfAnnotation(copy, TOC_Page.Left, ct.YLine, TOC_Page.Right, y, action);
    stamp.AddAnnotation(link);
    y = ct.YLine;
    

    这会正确创建页面。下面的代码调整了ToC2 example 的结尾以重新排序页面,以便处理超过 1 个页面。

    var rdr = new PdfReader(baos.toByteArray()); 
    var totalPageCount = rdr.NumberOfPages;
    rdr.SelectPages(String.Format("{0}-{1}, 1-{2}", totalPageCount - tocPageCount +1, totalPageCount, totalPageCount - tocPageCount));
    PdfStamper stamper = new PdfStamper(rdr, new FileStream(outputFilePath, FileMode.Create));
    stamper.Close();
    

    通过重新使用 CheckForNewPage 函数,您应该能够将任何内容添加到您创建的新页面,并使其跨越多个页面。如果您不需要注释,请在添加所有内容的末尾循环调用 CheckForNewPage(只是不要事先调用 ct.Go())。

    【讨论】:

      猜你喜欢
      • 2014-02-28
      • 2015-08-17
      • 1970-01-01
      • 1970-01-01
      • 2016-04-04
      • 2015-12-02
      • 2011-08-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多