使用java中的itext库为合并的pdf创建多页索引文件(TOC)

时间:2016-04-01 21:53:32

标签: c# pdf itext

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

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#中)

1 个答案:

答案 0 :(得分:0)

此答案基于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变量重置为新页面的顶部,以便链接注释位于新页面上的正确位置。

e.g。

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())。