在 java 中使用 itext 库为合并的 pdf 创建多页索引文件 (TOC)
Create Multi-page Index File(TOC) for merged pdf using itext library in java
如何使用 iTextSharp 将多页目录写入包含合并文档的 PDF 末尾?
Create Index File(TOC) for merged pdf using itext library in java explains how to create a ToC page when merging PDFs (catalogued in the iTextSharp book http://developers.itextpdf.com/examples/merging-pdf-documents/merging-documents-and-create-table-contents#795-mergewithtoc.java 的答案)。此答案中的代码基于这些示例。
然而,它仅在 ToC 为 1 页长时才有效。如果内容变长,那么它会在同一页上重复,而不是跨越到下一页。
尝试通过以下方式将 link 直接添加到文本中:
ct.Add(new Chunk("link").SetLocalGoto("p1"))
导致异常 ("Cannot add Annotations, not enough pages in document")。
任何人都可以解释一种方法,该方法允许我在合并时将多页内容附加到 PDF(方法越通用越好)。有没有一种方法可以使用 Document.Add() 写入文档,而不必复制模板页面并在其顶部写入?
(注意,代码在 c# 中)
此答案基于 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 returns 为真,您可以增加页面计数,并将 y 变量重置为新页面的顶部,以便 link 注释位于新页面的正确位置.
例如
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())。
如何使用 iTextSharp 将多页目录写入包含合并文档的 PDF 末尾?
Create Index File(TOC) for merged pdf using itext library in java explains how to create a ToC page when merging PDFs (catalogued in the iTextSharp book http://developers.itextpdf.com/examples/merging-pdf-documents/merging-documents-and-create-table-contents#795-mergewithtoc.java 的答案)。此答案中的代码基于这些示例。
然而,它仅在 ToC 为 1 页长时才有效。如果内容变长,那么它会在同一页上重复,而不是跨越到下一页。
尝试通过以下方式将 link 直接添加到文本中:
ct.Add(new Chunk("link").SetLocalGoto("p1"))
导致异常 ("Cannot add Annotations, not enough pages in document")。
任何人都可以解释一种方法,该方法允许我在合并时将多页内容附加到 PDF(方法越通用越好)。有没有一种方法可以使用 Document.Add() 写入文档,而不必复制模板页面并在其顶部写入?
(注意,代码在 c# 中)
此答案基于 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 returns 为真,您可以增加页面计数,并将 y 变量重置为新页面的顶部,以便 link 注释位于新页面的正确位置.
例如
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())。