如何使用 C# iText7 将 PDF 包中的所有 pdf 文件合并为普通 pdf 文件?

How to merge all pdf files from a PDF Portfolio to a normal pdf file using C# iText7?

this C# example 并尝试将附件作为 PdfDocument 获取,但我不知道该怎么做。

最后,我想简单地将投资组合中包含的每个 pdf 文件合并到一个“普通”pdf 文件中。应忽略每个非 pdf 附件。

编辑:

(好吧,抱歉说得太含糊了。说出我想要达到的目的,只是想让你们更容易帮助我。我不想让你们帮我写程序。)

因此,这是链接示例中的部分代码:

protected void ManipulatePdf(String dest)
{
    PdfDocument pdfDoc = new PdfDocument(new PdfReader(SRC), new PdfWriter(dest));

    PdfDictionary root = pdfDoc.GetCatalog().GetPdfObject();
    PdfDictionary names = root.GetAsDictionary(PdfName.Names);
    PdfDictionary embeddedFiles = names.GetAsDictionary(PdfName.EmbeddedFiles);
    PdfArray namesArray = embeddedFiles.GetAsArray(PdfName.Names);
    
    // Remove the description of the embedded file
    namesArray.Remove(0);

    // Remove the reference to the embedded file.
    namesArray.Remove(0);

    pdfDoc.Close();
}

我不想从源文档中删除任何内容,而是想知道如何在可能的情况下从 PdfArray 中获取 PdfDocument 对象。

示例文件: http://www.mediafire.com/file/c4tw07wci8swdx9/NPort_5000.pdf/file

移植到C#的mkl解决方案:

PdfNameTree embeddedFilesTree = pdfDocument.GetCatalog().GetNameTree(PdfName.EmbeddedFiles);
IDictionary<string, PdfObject> embeddedFilesMap = embeddedFilesTree.GetNames();
List<PdfStream> embeddedPdfs = new List<PdfStream>();
foreach (PdfObject pdfObject in embeddedFilesMap.Values)
{
    if (!(pdfObject is PdfDictionary))
        continue;
    PdfDictionary filespecDict = (PdfDictionary)pdfObject;
    PdfDictionary embeddedFileDict = filespecDict.GetAsDictionary(PdfName.EF);
    if (embeddedFileDict == null)
        continue;
    PdfStream embeddedFileStream = embeddedFileDict.GetAsStream(PdfName.F);
    if (embeddedFileStream == null)
        continue;
    PdfName subtype = embeddedFileStream.GetAsName(PdfName.Subtype);
    if (PdfName.ApplicationPdf.CompareTo(subtype) != 0)
        continue;
    embeddedPdfs.Add(embeddedFileStream);
}

if (embeddedPdfs.Count > 0)
{
    PdfWriter pdfWriter = new PdfWriter("NPort_5000-flat.pdf", new WriterProperties().SetFullCompressionMode(true));
    PdfDocument flatPdfDocument = new PdfDocument(pdfWriter);
    PdfMerger pdfMerger = new PdfMerger(flatPdfDocument);
    RandomAccessSourceFactory sourceFactory = new RandomAccessSourceFactory();
    foreach (PdfStream pdfStream in embeddedPdfs)
    {
        PdfReader embeddedReader = new PdfReader(sourceFactory.CreateSource(pdfStream.GetBytes()), new ReaderProperties());
        PdfDocument embeddedPdfDocument = new PdfDocument(embeddedReader);
        pdfMerger.Merge(embeddedPdfDocument, 1, embeddedPdfDocument.GetNumberOfPages());
    }
    flatPdfDocument.Close();
}

将 PDF 包中的所有 pdf 文件合并到普通 pdf 文件,您必须遍历 EmbeddedFiles 的名称树,检索其中所有PDF的流,然后合并所有这些PDF。

对于在 PdfDocument pdfDocument 中加载的投资组合(Java 版本;OP 在他的问题正文中编辑了一个 C# 端口):

PdfNameTree embeddedFilesTree = pdfDocument.getCatalog().getNameTree(PdfName.EmbeddedFiles);
Map<String, PdfObject> embeddedFilesMap = embeddedFilesTree.getNames();
List<PdfStream> embeddedPdfs = new ArrayList<PdfStream>();
for (Map.Entry<String, PdfObject> entry : embeddedFilesMap.entrySet()) {
    PdfObject pdfObject = entry.getValue();
    if (!(pdfObject instanceof PdfDictionary))
        continue;
    PdfDictionary filespecDict = (PdfDictionary) pdfObject;
    PdfDictionary embeddedFileDict = filespecDict.getAsDictionary(PdfName.EF);
    if (embeddedFileDict == null)
        continue;
    PdfStream embeddedFileStream = embeddedFileDict.getAsStream(PdfName.F);
    if (embeddedFileStream == null)
        continue;
    PdfName subtype = embeddedFileStream.getAsName(PdfName.Subtype);
    if (!PdfName.ApplicationPdf.equals(subtype))
        continue;
    embeddedPdfs.add(embeddedFileStream);
}

Assert.assertFalse("No embedded PDFs found", embeddedPdfs.isEmpty());

try (   PdfWriter pdfWriter = new PdfWriter("NPort_5000-flat.pdf", new WriterProperties().setFullCompressionMode(true));
        PdfDocument flatPdfDocument = new PdfDocument(pdfWriter)    ) {
    PdfMerger pdfMerger = new PdfMerger(flatPdfDocument);
    RandomAccessSourceFactory sourceFactory = new RandomAccessSourceFactory();
    for (PdfStream pdfStream : embeddedPdfs) {
        try (   PdfReader embeddedReader = new PdfReader(sourceFactory.createSource(pdfStream.getBytes()), new ReaderProperties());
                PdfDocument embeddedPdfDocument = new PdfDocument(embeddedReader)) {
            pdfMerger.merge(embeddedPdfDocument, 1, embeddedPdfDocument.getNumberOfPages());
        }
    }
}

(FlattenPortfolio 测试 testFlattenNPort_5000)