A PDF může obsahovat další soubory uvnitř. Může to být portfolio, které sdružuje smlouvy a tabulky, nebo zpráva s připojenými zdrojovými daty. Když v kódu tyto soubory vytáhnete, chcete, aby každý byl uložen pod názvem, který mu autor přiřadil, a ne attachment1.bin. Tento tutoriál ukazuje, jak extrahovat vložené soubory z PDF s původními názvy v C# pomocí Aspose.PDF for .NET. Otevřete PDF, projdete jeho vložené soubory, získáte název každého souboru pomocí FileSpecification.GetFileName a zapíšete obsah do složky.

Kde PDF ukládá název vloženého souboru

Každý vložený soubor je popsán specifikací souboru a specifikace souboru může zaznamenat název na více místech. Existuje název souboru v Unicode, standardní název souboru a klíč, pod kterým je soubor uveden ve sbírce vložených souborů dokumentu. Výrobci PDF tyto údaje nevyplňují konzistentně a někteří název úplně vynechají.

Aspose.PDF for .NET poskytuje vlastnost FileSpecification.GetFileName pro řešení tohoto. Rozpozná název z Unicode názvu, běžného názvu souboru nebo klíče kolekce, podle toho, který je k dispozici, takže i když Unicode název chybí, získáte použitelné jméno. Můžete předat náhradní název pro soubory, které vůbec nemají žádný název. Volitelný druhý parametr určuje, zda je povolen prázdný název, když není k dispozici žádný název souboru. Získáte jedno volání místo vlastní logiky pro čtení PDF slovníků.

Poznámka: Příklady v tomto článku používají pouze argument fallback.

Document.EmbeddedFiles obsahuje přílohy na úrovni dokumentu, které zahrnují soubory v PDF portfoliu. Soubory připojené k určité stránce pomocí anotace přílohy souboru (obvykle zobrazené jako ikona sponky) jsou uloženy přímo v anotaci; Extrahovat soubory připojené k stránkám se tím zabývá.

Použití Aspose.PDF k extrakci vložených souborů z PDF

Install-Package Aspose.PDF

Nebo s .NET CLI:

dotnet add package Aspose.PDF
  • PDF, který obsahuje vložené soubory. Příklad používá portfolio pojmenované PDFPortfolio.pdf.

Bez licence Aspose.PDF běží v evaluačním režimu. Pro testování bez omezení hodnocení požádejte o bezplatnou dočasnou licenci.

Extrahovat každý vložený soubor s jeho původním názvem

Následující metoda otevře PDF, uloží každý vložený soubor do výstupní složky pod jeho rozpoznaným názvem a vypíše cestu každého souboru, který zapíše.

using System;
using System.IO;
using Aspose.Pdf;

public static class EmbeddedFileExtractor
{
    public static void ExtractEmbeddedFiles(string inputPdf, string outputDir)
    {
        Directory.CreateDirectory(outputDir);

using (var document = new Document(inputPdf))
        {
            foreach (FileSpecification fileSpec in document.EmbeddedFiles)
            {
                // Resolve the stored name, then keep only the file name part.
                string fileName = Path.GetFileName(fileSpec.GetFileName("attachment.bin"));
                string outputPath = Path.Combine(outputDir, fileName);

using (var output = new FileStream(outputPath, FileMode.Create))
                {
                    fileSpec.Contents.CopyTo(output);
                }

Console.WriteLine($"Saved: {outputPath}");
            }
        }
    }
}

Zavolejte jej s cestou k PDF a složkou, do které chcete soubory umístit:

EmbeddedFileExtractor.ExtractEmbeddedFiles("PDFPortfolio.pdf", "ExtractedFiles");

Co dělá každý krok

Otevřete dokument. new Document(inputPdf) načte PDF. Blok using uvolní souborový handle po dokončení zpracování, i když dojde k vyhození výjimky.

Procházejte přílohy. document.EmbeddedFiles vrací jeden FileSpecification pro každý vložený soubor na úrovni dokumentu.

Vyřešte název. fileSpec.GetFileName("attachment.bin") vrací uložený název, nebo attachment.bin, pokud PDF žádný neposkytne. Vyberte náhradní řešení, které dává smysl pro vaši aplikaci.

Odstraňte segmenty složek. Uložený název může obsahovat cestu, například reports/2026/q3.xlsx, nebo uměle vytvořenou hodnotu, například ..\..\startup.bat. Předáním výsledku funkci Path.GetFileName se zredukuje na q3.xlsx nebo startup.bat, takže soubor nemůže být zapsán mimo outputDir. Uchovejte tento krok i v případě, že dnes důvěřujete PDF souborům, které zpracováváte.

Zapište obsah. fileSpec.Contents je proud dat vloženého souboru. CopyTo jej zapíše do nového souboru bez jakékoli konverze.

Očekávaný výsledek

Výstupní složka obsahuje jeden soubor pro každou přílohu na úrovni dokumentu, pojmenovaný tak, jak byl uložen v PDF. Pro portfolio, které obsahuje tabulku a dokument Word, výstup v konzoli vypadá podobně jako tento:

Saved: ExtractedFiles\budget-2026.xlsx
Saved: ExtractedFiles\service-agreement.docx

Názvy souborů závisí na vašem PDF. Extrahované soubory obsahují stejná data, která byla vložena, takže každý se otevře v aplikaci, která jeho formát podporuje.

Zpracování duplicitních a nebezpečných názvů

Základní příklad má tři slabé stránky, se kterými se setkáte u reálných PDF:

  • Dvě přílohy mohou mít stejné jméno a FileMode.Create tiše přepíše první. To se také stane, když několik příloh nemá jméno a všechny se vrátí na attachment.bin.
  • Název, který je platný v jednom operačním systému, může obsahovat znaky, které jsou v jiném neplatné, například : ve Windows.
  • Uložený název, který končí oddělovačem cesty, způsobí, že Path.GetFileName vrátí prázdný řetězec.

Tento pomocník řeší všechny tři. Nahrazuje neplatné znaky, vrací výchozí hodnotu, když je název prázdný, a přidává čítač, když soubor již existuje:

private static string GetSafeOutputPath(string outputDir, string resolvedName, string fallbackName)
{
    string fileName = Path.GetFileName(resolvedName);

foreach (char c in Path.GetInvalidFileNameChars())
    {
        fileName = fileName.Replace(c, '_');
    }

if (string.IsNullOrWhiteSpace(fileName))
    {
        fileName = fallbackName;
    }

string baseName = Path.GetFileNameWithoutExtension(fileName);
    string extension = Path.GetExtension(fileName);
    string outputPath = Path.Combine(outputDir, fileName);

int counter = 1;
    while (File.Exists(outputPath))
    {
        outputPath = Path.Combine(outputDir, $"{baseName} ({counter}){extension}");
        counter++;
    }

return outputPath;
}

V cyklu extrakce nahraďte dva řádky, které vytvářejí fileName a outputPath, následujícím:

string outputPath = GetSafeOutputPath(outputDir, fileSpec.GetFileName("attachment.bin"), "attachment.bin");

Protože pomocník kontroluje existující soubory, spuštění extrakce dvakrát do stejné složky vytvoří číslované kopie místo přepsání. Vyčistěte složku nejprve, pokud chcete při každém spuštění čerstvý výsledek.

Extrahovat soubory připojené k stránkám

Pokud je EmbeddedFiles prázdný, ale v prohlížeči PDF vidíte ikonu sponky, soubor je pravděpodobně připojen pomocí anotace přílohy souboru na stránce. Anotace obsahuje vlastní FileSpecification ve vlastnosti File, takže se použije stejná resoluce názvu i stejný pomocník. Tato metoda prochází každou stránku a ukládá každý připojený soubor do výstupní složky:

using Aspose.Pdf.Annotations;

public static void ExtractPageAttachments(string inputPdf, string outputDir)
{
    Directory.CreateDirectory(outputDir);

using (var document = new Document(inputPdf))
    {
        foreach (Page page in document.Pages)
        {
            foreach (Annotation annotation in page.Annotations)
            {
                if (annotation is FileAttachmentAnnotation attachment && attachment.File != null)
                {
                    string outputPath = GetSafeOutputPath(outputDir, attachment.File.GetFileName("attachment.bin"), "attachment.bin");

using (var output = new FileStream(outputPath, FileMode.Create))
                    {
                        attachment.File.Contents.CopyTo(output);
                    }

Console.WriteLine($"Saved: {outputPath}");
                }
            }
        }
    }
}

Chcete‑li shromáždit všechny přílohy v PDF, spusťte obě metody se stejnou výstupní složkou. Pokud PDF odkazuje na stejný soubor z obou míst, GetSafeOutputPath uloží druhou kopii pod číslovaným názvem místo přepsání první.

Další kroky

Pro další práci s přílohami, jako je přidávání, odstraňování nebo výpis bez rozbalení, viz dokumentace Aspose.PDF for .NET dokumentace. Odkaz FileSpecification reference třídy uvádí další vlastnosti name a description, které můžete číst z každého vloženého souboru. Pokud PDF není rozbaleno podle očekávání, pošlete ukázku do Aspose.PDF fórum podpory.

FAQs

  1. Jak FileSpecification.GetFileName vybírá název? Rozhodne název z Unicode názvu vloženého souboru, běžného názvu souboru nebo klíče kolekce, podle toho, který je k dispozici. Pokud žádný není k dispozici, vrátí náhradní název, který předáte. Metoda byla přidána v Aspose.PDF for .NET 26.9.

  2. Funguje to i pro PDF soubory, které nejsou portfolii?
    Ano, pro soubory připojené na úrovni dokumentu. Soubory připojené ke konkrétní stránce pomocí anotace připojení souboru (obvykle zobrazené jako ikona sponky) jsou uloženy na anotaci, takže je načtěte z FileAttachmentAnnotation.File, jak je ukázáno v Extract files attached to pages.

  3. Proč obalit výsledek GetFileName metodou Path.GetFileName? Název uložený v PDF je nastaven tím, kdo soubor vytvořil, a může obsahovat segmenty složek. Path.GetFileName zachová pouze název souboru, takže každá příloha je zapsána do vašeho výstupního adresáře.

  4. Co se stane, pokud mají dva přílohy stejný název? S FileMode.Create druhý soubor přepíše první. Zkontrolujte, zda cesta již existuje, a přidejte číselnou příponu, jak je ukázáno v Zvládání duplicitních a nebezpečných názvů.

  5. Mohu zpracovat přílohu, aniž bych ji ukládal na disk?
    Ano. Vlastnost Contents je Stream, takže ji můžete zkopírovat do MemoryStream, nahrát ji nebo předat jiné knihovně místo zápisu do FileStream.