修改现有 pdf(添加/删除页面),同时保留元数据

本文关键字:元数据 保留 删除 pdf 添加 修改 | 更新日期: 2023-09-27 18:35:31

我的目标是打开现有的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());
        }
    }
}

修改现有 pdf(添加/删除页面),同时保留元数据

需要进行两项更改。 叫

concatenator.Writer.CloseStream = false

打电话前

concatenator.Close()

对PdfStamper做同样的事情,你就设置好了。