Измените существующий PDF-файл (добавьте/удалите страницы) с сохранением метаданных

моя цель - открыть существующий PDF-файл, добавить или удалить некоторые страницы, сохраняя при этом метаданные (автор, тема,...) в приложении Windows.Forms C#.

Я использую iTextSharp и нашел примеры добавления или удаления страниц с помощью класса PdfConcatenate. Чтобы сохранить метаданные, я впоследствии использую PdfStamper. Чтобы ускорить процесс, я хочу внести изменения в память перед сохранением результата на диск.

Проблема НЕ в добавлении или удалении страниц, а в сохранении метаданных на том же этапе. Так может ли кто-нибудь рассказать мне/giva пример того, как этого добиться (лучше), или я на совершенно неправильном пути?

Вот мой текущий код (см. комментарии к строкам, связанным с проблемой):

public void RemovePagesInFile(string documentLocation, int pageIndexFrom, int pageCount)
{
    // TB: open the pdf
    using (PdfReader sourcePdfReader = new PdfReader(documentLocation))
    using (MemoryStream concatenatedTargetStream = new MemoryStream((int)sourcePdfReader.FileLength))
    {
        // TB: use a concatenator to create a new pdf containing only the desired pages
        PdfConcatenate concatenator = new PdfConcatenate(concatenatedTargetStream);

        // TB: create a list with the page numbers to keep
        List<int> pagesToKeep = new List<int>();
        for (int i = 1; i <= pageIndexFrom; i++)
        {
            pagesToKeep.Add(i);
        }

        for (int i = pageIndexFrom + pageCount + 1; i <= sourcePdfReader.NumberOfPages; i++)
        {
            pagesToKeep.Add(i);
        }

        // TB: execute the page copy
        sourcePdfReader.SelectPages(pagesToKeep);
        concatenator.AddPages(sourcePdfReader);

        // TB: problem(s) here:
        // 1. when calling concatenator.Close() the memory stream gets disposed as expected.
        // concatenator.Close();
        // 2. even when calling concatenator.WriterFlush() the memory stream seems to be missing content (error when creating targetReader (see below)).
        // concatenator.Writer.Flush();
        // 3. when keeping concatenator open the same error as above occures (I assume not all bytes have been written to the memory stream)

        // TB: preserve the meta data from the source document
        // => ERROR here: "Rebuild trailer not found. Original Error: PDF startxref not found"
        using (PdfReader targetReader = new PdfReader(concatenatedTargetStream))
        using (MemoryStream targetStream = new MemoryStream((int)concatenatedTargetStream.Length))
        {
            using (PdfStamper stamper = new PdfStamper(targetReader, targetStream))
            {
                stamper.MoreInfo = sourcePdfReader.Info;

                // TB: same problem as above with stamper ?
                stamper.Close();
            }

            // TB: close the reader to be able to access the source pdf
            sourcePdfReader.Close();

            // TB: write the modified pdf to the disk
            File.WriteAllBytes(documentLocation, targetStream.ToArray());
        }
    }
}

person me.    schedule 15.10.2013    source источник
comment
У меня не более 10 очков репутации, поэтому кто-нибудь может опубликовать в качестве ответа следующее: ... РЕДАКТИРОВАТЬ: тоже не работает - текст слишком длинный для комментариев grrrr   -  person me.    schedule 15.10.2013
comment
Просто и понятно: решение состоит в том, чтобы внести два изменения: вызвать concatenator.Writer.CloseStream = false перед вызовом concatenator.Close() и то же самое для PdfStamper. Так что, если кто-нибудь с большей репутацией добавит это в качестве ответа: Спасибо!   -  person me.    schedule 15.10.2013


Ответы (1)


Необходимо внести два изменения. Вызов

concatenator.Writer.CloseStream = false

прежде чем звонить

concatenator.Close()

Сделайте то же самое для PdfStamper, и все готово.

person ovaltein    schedule 29.10.2013