У меня есть процесс, который объединяет несколько PDF-файлов в один PDF-файл. Это отлично работает.Вставить PieceInfo в объединенный документ с ITextSharp
Во время слияния я хочу добавить PieceInfo на уровне страницы, чтобы отслеживать документы, которые были включены в этот объединенный файл.
Предположим, у меня есть 3 документа в этом порядке: Fester.pdf (2 страницы), Gomez.pdf (2 страницы) и Lurch.pdf (1 страница). После слияния у меня будет 5 страниц, и каждая страница будет иметь PieceInfo с именем файла, из которого был создан. Таким образом, если я перейду на страницу 4, я узнаю, что страница была создана из Gomez.pdf
Во время моего поиска я нашел это сообщение: Insert hidden digest in pdf using iText library, и я попытался реализовать то же самое в моем процессе. Предложение работает отлично, но я не мог понять, как хранить информацию на странице.
Вот мой код:
public static byte[] MergeDocuments(DocumentCollection myCollection)
{
PdfImportedPage importedPage = null;
// Merged the document streams
using (MemoryStream stream = new MemoryStream())
{
// Create the iTextSharp document
iTextSharp.text.Document pdfDoc = new iTextSharp.text.Document();
// Create the PDF writer that listened to the document
PdfCopy pdfCopy = new PdfCopy(pdfDoc, stream);
if (pdfDoc != null && pdfCopy != null)
{
// Open the document and load content
pdfDoc.Open();
//Dictionary Entries
PdfName appName = new PdfName("MyKey");
PdfName dataName = new PdfName("Hash");
//Class to add and retrieve the PieceInfo data
DocumentPieceInfo dpi = new DocumentPieceInfo();
//Loop through my collection. The document class has the BinaryFile and FileName
foreach (Document doc in myCollection)
{
PdfReader reader = new PdfReader(doc.FileBinary);
if (reader != null)
{
int nPage = reader.NumberOfPages;
for (int n = 0; n < nPage; n++)
{
//Trying to add the PieceInfo
dpi.addPieceInfo(pdfCopy, appName, dataName, new PdfString(string.Format("Info Doc: {0}", doc.FileName)));
importedPage = pdfCopy.GetImportedPage(reader, n + 1);
pdfCopy.AddPage(importedPage);
}
// Close the reader
reader.Close();
}
}
if (pdfCopy != null)
pdfCopy.Close();
if (pdfDoc != null)
pdfDoc.Close();
byte[] arrOutput = stream.ToArray();
return arrOutput;
}
}
return null;
}
И небольшое изменение в решение MKL, меняя вход в PDFCopy:
public void addPieceInfo(PdfCopy reader, PdfName app, PdfName name, PdfObject value)
{
//PdfDictionary catalog = reader.getCatalog();
PdfDictionary pieceInfo = reader.ExtraCatalog.GetAsDict(PIECE_INFO);
if (pieceInfo == null)
{
pieceInfo = new PdfDictionary();
reader.ExtraCatalog.Put(PIECE_INFO, pieceInfo);
}
PdfDictionary appData = pieceInfo.GetAsDict(app);
if (appData == null)
{
appData = new PdfDictionary();
pieceInfo.Put(app, appData);
}
PdfDictionary privateData = appData.GetAsDict(PRIVATE);
if (privateData == null)
{
privateData = new PdfDictionary();
appData.Put(PRIVATE, privateData);
}
appData.Put(LAST_MODIFIED, new PdfDate());
privateData.Put(name, value);
}
Код выше добавления pieceinfo на последней странице только :(
ли объект страницы PdfImportedPage есть способ получить каталог?
Как включить эту информацию на уровень страницы во время моего процесса слияния? После этого, как я могу получить часть информации со страниц? Просто перебираете страницы?
Класс «DocumentPieceInfo» из моего старого ответа работает только со структурой * Document-wide * ** PieceInfo **. Если вы хотите разместить информацию на каждой странице, имя для этой информации должно каким-то образом включать страницу, например. 'new PdfName (« Хеш »+ номер страницы)'. Поскольку страницы в документе могут быть позже удалены или вставлены, это не является оптимальным. Вам лучше использовать * page-level * ** PieceInfo ** структуры или (из-за неминуемой ** PieceInfo ** устаревания) * на уровне страницы * личные ключи, зарегистрированные вам, ср. @Brunos abswer. – mkl