使用 iText7 从现有 PDF 获取所有元数据

Get all metadata from an existing PDF using iText7

如何使用 iText7 检索存储在 PDF 中的所有元数据?

using (var pdfReader = new iText.Kernel.Pdf.PdfReader("path-to-a-pdf-file"))
{
    var pdfDocument = new iText.Kernel.Pdf.PdfDocument(pdfReader);
    var pdfDocumentInfo = pdfDocument.GetDocumentInfo();

    // Getting basic metadata
    var author = pdfDocumentInfo.GetAuthor();
    var title = pdfDocumentInfo.GetTitle();

    // Getting everything else
    var someMetadata = pdfDocumentInfo.GetMoreInfo("need-a-key-here");
    // How to get all metadata ?
}

我在 iTextSharp 中使用它,但我不知道如何在新的 iText7 中使用它。

using (var pdfReader = new iTextSharp.text.pdf.PdfReader("path-to-a-pdf-file"))
{
    // Getting basic metadata
    var author = pdfReader.Info.ContainsKey("Author") ? pdfReader.Info["Author"] : null;
    var title = pdfReader.Info.ContainsKey("Title") ? pdfReader.Info["Title"] : null;

    // Getting everything else
    var metadata = pdfReader.Info;
    metadata.Remove("Author");
    metadata.Remove("Title");

    // Print metadata
    Console.WriteLine($"Author: {author}");
    Console.WriteLine($"Title: {title}");

    foreach (var line in metadata)
    {
        Console.WriteLine($"{line.Key}: {line.Value}");
    }
}

我使用的是 iText7 的 7.1.1 版本。

不幸的是,在 iText 7 中,PdfDocumentInfo class 没有公开检索底层字典中的键的方法。

但是您可以通过立即从预告片字典访问该字典来简单地检索信息字典内容。例如。对于 PdfDocument pdfDocument:

PdfDictionary infoDictionary = pdfDocument.GetTrailer().GetAsDictionary(PdfName.Info);
foreach (PdfName key in infoDictionary.KeySet())
    Console.WriteLine($"{key}: {infoDictionary.GetAsString(key)}");

"UnicodeBig""UTF-8""PDF" 编码字符串有问题。
比如PDF是用Microsoft Word创建的,那么"/Creator"是编码不可读的,需要转换:
.
iText7 有自己的转换功能: ...ToUnicodeString().
但它是 PdfString 对象的方法,PdfDictionary 值 (PdfObject) 必须首先转换为此 PdfString 类型。
async、"unbreakable" 和自动处理功能的完整解决方案:

public static async Task<(Dictionary<string, string> MetaInfo, string Error)> GetMetaInfoAsync(string path)
{
    try
    {
        var metaInfo = await Task.Run(() =>
        {
            var metaInfoDict = new Dictionary<string, string>();
            using (var pdfReader = new PdfReader(path))
            using (var pdfDocument = new PdfDocument(pdfReader))
            {
                metaInfoDict["PDF.PageCount"] = $"{pdfDocument.GetNumberOfPages():D}";
                metaInfoDict["PDF.Version"] = $"{pdfDocument.GetPdfVersion()}";

                var pdfTrailer = pdfDocument.GetTrailer();
                var pdfDictInfo = pdfTrailer.GetAsDictionary(PdfName.Info);
                foreach (var pdfEntryPair in pdfDictInfo.EntrySet())
                {
                    var key = "PDF." + pdfEntryPair.Key.ToString().Substring(1);
                    string value;
                    switch (pdfEntryPair.Value)
                    {
                        case PdfString pdfString:
                            value = pdfString.ToUnicodeString();
                            break;
                        default:
                            value = pdfEntryPair.Value.ToString();
                            break;
                    }
                    metaInfoDict[key] = value;
                }
                return metaInfoDict;
            }
        });
        return (metaInfo, null);
    }
    catch (Exception ex)
    {
        if (Debugger.IsAttached) Debugger.Break();
        return (null, ex.Message);
    }
}