2016-04-01 7 views
0

Как написать многостраничный ToC в конец PDF, состоящий из объединенных документов, используя iTextSharp?Создать многостраничный индексный файл (TOC) для объединенного pdf с использованием библиотеки itext в java

Ответ на вопрос Create Index File(TOC) for merged pdf using itext library in java объясняет, как создать страницу ToC при слиянии PDF-файлов (каталогизировано в книге 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#)

ответ

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; 
    } 

Это должно вызываться каждый раз текст добавляется к переменной каратного.

Если 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() заранее).

Смежные вопросы