C# 导入pdf格式的命名目的地

C# 导入pdf格式的命名目的地,c#,pdf,itextsharp,C#,Pdf,Itextsharp,我正在开发一个应用程序,其中word文档转换为pdf格式。我的问题太复杂了,请帮我解决 我的word文档有目录、书签、尾注和超链接。当我将此文档另存为pdf时,仅转换书签。经过长时间的研究,我发现PDF文档不支持书签到书签的超链接,它需要页码或指定目的地 为此,我选择了命名目的地,但我再次陷入困境,因为simple“save as”无法在pdf文档中生成命名目的地。因此,我在AdobePDF打印机上打印word文档,并根据需要指定了目的地,但该文档中既没有书签,也没有超链接。所以我决定从一个单词

我正在开发一个应用程序,其中word文档转换为pdf格式。我的问题太复杂了,请帮我解决

我的word文档有目录、书签、尾注和超链接。当我将此文档另存为pdf时,仅转换书签。经过长时间的研究,我发现PDF文档不支持书签到书签的超链接,它需要页码或指定目的地

为此,我选择了命名目的地,但我再次陷入困境,因为simple
“save as
”无法在pdf文档中生成命名目的地。因此,我在AdobePDF打印机上打印word文档,并根据需要指定了目的地,但该文档中既没有书签,也没有超链接。所以我决定从一个单词生成两个pdf,第一个是通过“另存为”选项,第二个是通过打印

  • test.pdf(另存为)(包含书签、超链接)
  • test_p.pdf(打印)(仅包含指定目的地)
  • 然后我再次研究了它们,找到了一种方法,通过itextsharp的函数将所有指定目的地从
    test\p.pdf
    提取到XML中。但不幸的是,我没有办法在
    test.pdf
    中重新导入此
    XML
    。。这就是我来这里的原因


    如果这种方法可行,请指导我下一步要做什么。否则,请向我推荐任何其他方法来完成此任务。

    几天前,我编写了一个类来替换PDF文件中的URL:

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using iTextSharp.text.pdf;
    
    namespace ReplaceLinks
    {
        public class ReplacePdfLinks
        {
            Dictionary<string, PdfObject> _namedDestinations;
            PdfReader _reader;
    
            public string InputPdf { set; get; }
            public string OutputPdf { set; get; }
            public Func<Uri, string> UriToNamedDestination { set; get; }
    
            public void Start()
            {
                updatePdfLinks();
                saveChanges();
            }
    
            private PdfArray getAnnotationsOfCurrentPage(int pageNumber)
            {
                var pageDictionary = _reader.GetPageN(pageNumber);
                var annotations = pageDictionary.GetAsArray(PdfName.ANNOTS);
                return annotations;
            }
    
            private static bool hasAction(PdfDictionary annotationDictionary)
            {
                return annotationDictionary.Get(PdfName.SUBTYPE).Equals(PdfName.LINK);
            }
    
            private static bool isUriAction(PdfDictionary annotationAction)
            {
                return annotationAction.Get(PdfName.S).Equals(PdfName.URI);
            }
    
            private void replaceUriWithLocalDestination(PdfDictionary annotationAction)
            {
                var uri = annotationAction.Get(PdfName.URI) as PdfString;
                if (uri == null)
                    return;
    
                if (string.IsNullOrWhiteSpace(uri.ToString()))
                    return;
    
                var namedDestination = UriToNamedDestination(new Uri(uri.ToString()));
                if (string.IsNullOrWhiteSpace(namedDestination))
                    return;
    
                PdfObject entry;
                if (!_namedDestinations.TryGetValue(namedDestination, out entry))
                    return;
    
                annotationAction.Remove(PdfName.S);
                annotationAction.Remove(PdfName.URI);
    
                var newLocalDestination = new PdfArray();
                annotationAction.Put(PdfName.S, PdfName.GOTO);
                var xRef = ((PdfArray)entry).First(x => x is PdfIndirectReference);
                newLocalDestination.Add(xRef);
                newLocalDestination.Add(PdfName.FITH);
                annotationAction.Put(PdfName.D, newLocalDestination);
            }
    
            private void saveChanges()
            {
                using (var fileStream = new FileStream(OutputPdf, FileMode.Create, FileAccess.Write, FileShare.None))
                using (var stamper = new PdfStamper(_reader, fileStream))
                {
                    stamper.Close();
                }
            }
    
            private void updatePdfLinks()
            {
                _reader = new PdfReader(InputPdf);
                _namedDestinations = _reader.GetNamedDestinationFromStrings();
    
                var pageCount = _reader.NumberOfPages;
                for (var i = 1; i <= pageCount; i++)
                {
                    var annotations = getAnnotationsOfCurrentPage(i);
                    if (annotations == null || !annotations.Any())
                        continue;
    
                    foreach (var annotation in annotations.ArrayList)
                    {
                        var annotationDictionary = (PdfDictionary)PdfReader.GetPdfObject(annotation);
    
                        if (!hasAction(annotationDictionary))
                            continue;
    
                        var annotationAction = annotationDictionary.Get(PdfName.A) as PdfDictionary;
                        if (annotationAction == null)
                            continue;
    
                        if (!isUriAction(annotationAction))
                            continue;
    
                        replaceUriWithLocalDestination(annotationAction);
                    }
                }
            }
        }    
    }
    
    此示例将修改包含google.com的所有URL,以指向特定的命名目的地“entry1”。 这是测试上述类的示例文件:

    void WriteFile()
    {
        using (var doc = new Document(PageSize.LETTER))
        {
            using (var fs = new FileStream("test.pdf", FileMode.Create))
            {
                using (var writer = PdfWriter.GetInstance(doc, fs))
                {
                    doc.Open();
                    var blueFont = FontFactory.GetFont("Arial", 12, Font.NORMAL, BaseColor.BLUE);
                    doc.Add(new Chunk("Go to URL", blueFont).SetAction(new PdfAction("http://www.google.com/", false)));
    
                    doc.NewPage();
                    doc.Add(new Chunk("Go to Test", blueFont).SetLocalGoto("entry1"));
    
                    doc.NewPage();
                    doc.Add(new Chunk("Test").SetLocalDestination("entry1"));
    
                    doc.Close();
                }
            }
        }
    }
    
    void WriteFile()
    {
        using (var doc = new Document(PageSize.LETTER))
        {
            using (var fs = new FileStream("test.pdf", FileMode.Create))
            {
                using (var writer = PdfWriter.GetInstance(doc, fs))
                {
                    doc.Open();
                    var blueFont = FontFactory.GetFont("Arial", 12, Font.NORMAL, BaseColor.BLUE);
                    doc.Add(new Chunk("Go to URL", blueFont).SetAction(new PdfAction("http://www.google.com/", false)));
    
                    doc.NewPage();
                    doc.Add(new Chunk("Go to Test", blueFont).SetLocalGoto("entry1"));
    
                    doc.NewPage();
                    doc.Add(new Chunk("Test").SetLocalDestination("entry1"));
    
                    doc.Close();
                }
            }
        }
    }