枚举命名目的地
Enumerate named destinations
我正在玩 iText 7
,但在获取命名目的地列表时遇到问题。
对于之前的版本 5,使用助手非常简单:
using (var reader = new PdfReader(_file))
{
var items = SimpleNamedDestination.GetNamedDestination(reader, false).Select(o => o.Key).ToList();
...
}
在 7 中我找不到帮手了,不得不使用这个怪物(改编自 official java example 的代码):
using (var reader = new PdfDocument(new PdfReader(file)))
{
var catalog = reader.GetCatalog().GetPdfObject();
var names = catalog.GetAsDictionary(PdfName.Names);
var dests = names.GetAsDictionary(PdfName.Dests);
var name = dests.GetAsArray(PdfName.Names); // problem
var items = new List<string>();
for (int i = 0; i < name.Size(); i += 2)
items.Add(name.GetAsString(i).ToString());
...
}
此外,对于某些 PDF,由于 null
在 GetAsArray
行返回,此代码失败并显示 NullReferenceException
。
仔细观察 PdfDictionary
和 PdfArray
类型 - 它们只有 1 个条目,没有枚举器 (!),没有 LINQ 支持。
我的问题:
- (基于意见,但我很想知道答案)为什么 iText 7 的功能少于 5?我想把两者混合吗?
- (请求场外资源)某处是否有适当的 C# iText 7 文档?从 java 转换并在 SO 上过滤几十个关于它的问题是非常低效的。
- (有点咆哮)我到底应该如何调试这些类型?谈到
PdfDictionary
,它显示 1 个条目,可能尚未解析 PDF 的内容。我想看看为什么 GetAsArray
失败了,但是我没有办法调试它。
- (实际问题)为什么上面的代码对于某些包含指定目的地的 pdf 失败(例如 this one,但我在本地有更多)?
我是不是做错了什么?
我不懂 C#,但在 Java 中,可以使用 getNameTree()
方法获取名称树。我假设 iText 7 的 C# 版本中存在类似的方法 GetNameTree()
:
Map<String, PdfObject> names =
pdfDoc.getCatalog().getNameTree(PdfName.Dests).getNames();
for (Map.Entry<String, PdfObject> name : names.entrySet()) {
System.out.println("Name = " + name.getKey());
System.out.println("Page = " + name.getValue().toString());
}
如果你能用 C# 语法更新我的答案,如果事实证明我的答案有帮助,那就太好了。
C#:
using (var pdf = new PdfDocument(new PdfReader(file)))
{
var names = pdf.GetCatalog().GetNameTree(PdfName.Dests).GetNames().Select(o => o.Key).ToList();
...
}
我正在玩 iText 7
,但在获取命名目的地列表时遇到问题。
对于之前的版本 5,使用助手非常简单:
using (var reader = new PdfReader(_file))
{
var items = SimpleNamedDestination.GetNamedDestination(reader, false).Select(o => o.Key).ToList();
...
}
在 7 中我找不到帮手了,不得不使用这个怪物(改编自 official java example 的代码):
using (var reader = new PdfDocument(new PdfReader(file)))
{
var catalog = reader.GetCatalog().GetPdfObject();
var names = catalog.GetAsDictionary(PdfName.Names);
var dests = names.GetAsDictionary(PdfName.Dests);
var name = dests.GetAsArray(PdfName.Names); // problem
var items = new List<string>();
for (int i = 0; i < name.Size(); i += 2)
items.Add(name.GetAsString(i).ToString());
...
}
此外,对于某些 PDF,由于 null
在 GetAsArray
行返回,此代码失败并显示 NullReferenceException
。
仔细观察 PdfDictionary
和 PdfArray
类型 - 它们只有 1 个条目,没有枚举器 (!),没有 LINQ 支持。
我的问题:
- (基于意见,但我很想知道答案)为什么 iText 7 的功能少于 5?我想把两者混合吗?
- (请求场外资源)某处是否有适当的 C# iText 7 文档?从 java 转换并在 SO 上过滤几十个关于它的问题是非常低效的。
- (有点咆哮)我到底应该如何调试这些类型?谈到
PdfDictionary
,它显示 1 个条目,可能尚未解析 PDF 的内容。我想看看为什么GetAsArray
失败了,但是我没有办法调试它。 - (实际问题)为什么上面的代码对于某些包含指定目的地的 pdf 失败(例如 this one,但我在本地有更多)?
我是不是做错了什么?
我不懂 C#,但在 Java 中,可以使用 getNameTree()
方法获取名称树。我假设 iText 7 的 C# 版本中存在类似的方法 GetNameTree()
:
Map<String, PdfObject> names =
pdfDoc.getCatalog().getNameTree(PdfName.Dests).getNames();
for (Map.Entry<String, PdfObject> name : names.entrySet()) {
System.out.println("Name = " + name.getKey());
System.out.println("Page = " + name.getValue().toString());
}
如果你能用 C# 语法更新我的答案,如果事实证明我的答案有帮助,那就太好了。
C#:
using (var pdf = new PdfDocument(new PdfReader(file)))
{
var names = pdf.GetCatalog().GetNameTree(PdfName.Dests).GetNames().Select(o => o.Key).ToList();
...
}