gpt4 book ai didi

c# - 以 pdf 格式导入命名目的地

转载 作者:太空宇宙 更新时间:2023-11-03 11:05:52 26 4
gpt4 key购买 nike

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

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

因此我为此选择了命名目的地,但我又被卡住了,因为简单的“另存为”无法在pdf文档中生成命名目的地。因此,我在 adobe PDF 打印机上打印了 doc 一词,并根据需要命名了目的地,但该文档同样既没有书签也没有超链接。所以我决定从一个单词生成两个 pdf,第一个是另存为选项,第二个是打印。

  1. test.pdf(另存为)(包含书签、超链接)
  2. 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);
}
}
}
}
}

使用方法:

    new ReplacePdfLinks
{
InputPdf = @"test.pdf",
OutputPdf = "mod.pdf",
UriToNamedDestination = uri =>
{
if (uri.Host.ToLowerInvariant().Contains("google.com"))
{
return "entry1";
}

return string.Empty;
}
}.Start();

此示例将修改所有包含 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();
}
}
}
}

关于c# - 以 pdf 格式导入命名目的地,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15847730/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com