この質問への答えをお読みください:Java: Reading PDF bookmark names with itext
それはあなたがアウトラインツリーのタイトルを取得するためにSimpleBookmark
メソッドを使用する方法について説明(これは、PDF仕様で「ブックマーク」が呼び出される方法です)。 Set inherit Zoom(action property) to bookmark in the pdf file
あなたはHashMap<String, Object>
が唯一のキー"Title"
を持つエントリが含まれていないことがわかりますが、それはまた、キー"Page"
を持つエントリを含むことができること:
public void inspectPdf(String filename) throws IOException, DocumentException {
PdfReader reader = new PdfReader(filename);
List<HashMap<String,Object>> bookmarks = SimpleBookmark.getBookmark(reader);
for (int i = 0; i < bookmarks.size(); i++){
showTitle(bookmarks.get(i));
}
reader.close();
}
public void showTitle(HashMap<String, Object> bm) {
System.out.println((String)bm.get("Title"));
List<HashMap<String,Object>> kids = (List<HashMap<String,Object>>)bm.get("Kids");
if (kids != null) {
for (int i = 0; i < kids.size(); i++) {
showTitle(kids.get(i));
}
}
}
は、この質問への回答を読んでください。ブックマークがページを指す場合です。値は明示的な宛先になります。ページ番号、Fit
、FitH
、FitB
、XYZ
などの値と、位置を示すいくつかのパラメータで構成されます。
あなたはCreateOutlineTree例を見れば、あなたはまた、XMLファイルとしてブックマークを抽出できることがわかります:
public void createXml(String src, String dest) throws IOException {
PdfReader reader = new PdfReader(src);
List<HashMap<String, Object>> list = SimpleBookmark.getBookmark(reader);
SimpleBookmark.exportToXML(list,
new FileOutputStream(dest), "ISO8859-1", true);
reader.close();
}
これは、あなたが示して、私はiTextのについて書いた本からのスクリーンショットですブックマークのエントリーに期待することができますキー:あなたはこの表から言うことができるように
、リンクもという名前の先として表現することができます。その場合は、ページ番号を取得するのではなく、名前を取得します。ページ番号を取得するには、名前付き宛先のリストを抽出する必要があります。このリストは、指定された宛先に対応する明示的な宛先を取得します。
これは、書籍とofficial documentationでも説明されています。
タイトルとページ番号(上記のポインタに基づいて記述されたコードで取得)を取得したら、PdfStamper
とinsertPage()
メソッドを使用してページをPDFファイルに挿入できます。ColumnText
を使用してこれらのページに目次を付けることもできますし、目次用に別のPDFを作成して元の目次とマージすることもできます。これら2つの手法の詳細については、How to add a cover/PDF in a existing iText documentを参照してください。
ます。また、この例の恩恵を受ける:Create Index File(TOC) for merged pdf using itext library in java
をタイトルとページ番号の間の破線については、そのはセパレーター、より具体的に点線の区切りを使用して行われます。あなたは最初にこの質問をお読みください:iTextSharp - Is it possible to set a different alignment in the same cell for text
は、この質問を読んで:How to Generate Table-of-Figures Dot Leaders in a PdfPCell for the Last Line of Wrapped Text(またはこの質問It is possible with itext 5 which at the end of a paragraph justified the remaining space is filled with scripts?)あなたの質問がオフトピック実際に
注意を。それは「家事」の問題として表現されています。それは人々があなたの場所であなたの仕事をするように促します。あなたが必要とするすべての要素を持っているので、自分で仕事をすることができるはずです。成功しない場合は、トピックのStack Overflowに関する質問を書く必要があります。それはあなたが試したことを示し、あなたが経験する技術的な問題を説明するための質問です。
更新:
次のアウトラインツリーでドキュメントを共有:
をあなたが見ることができるように、ブックマークは、このような/__WKANCHOR_2
、/__WKANCHOR_4
という名前の宛先を、使用して定義され、等々。 /
文字から分かるように、名前はPDF文字列オブジェクト(1.2以降)ではなく、PDF名前オブジェクト(PDF 1.1)として保存されます。最新のPDF標準では、PDF名前オブジェクトの代わりにPDF文字列オブジェクトを使用することを推奨しています。最新のPDF標準の推奨を満たすように、ソフトウェアを更新するようにPDF生成ソフトウェアのベンダーに依頼してください。
しかし、名前の付いた宛先に対応する明示的な宛先を簡単に取得できます。あなたは目的地は、あなたがwkhtmltopdfに報告しなければならない別の問題を見る方法を見てみると
:彼らは、ルート辞書の/Dests
エントリに格納されています。のは、ISO規格では、目的地に使用する構文について教えてくれるものを見てみましょう:
ページ番号の概念がPDFに存在しません。ページはページ辞書を使用して記述され、ページ番号はページツリー内のページの位置から得られます。ページツリーで検出される最初のページはページ1であり、2番目のページはページ2であり、以下同様です。
例では、説明先は次のように定義されています。、[9/XYZ 30.2400000 231.379999 0]
など。
これは間違っています。 ISO規格では、配列の最初の値は間接参照である必要があります。間接参照は9
ではなく9 0 R
の形式です。私はドキュメントの構造を見て、wkhtmltopdfが間接参照の代わりにページ番号-1を使用していることがわかりました。 /__WKANCHOR_2
を見ると[0/XYZ 30.240000 781.459999 0]
、0
は1ページ目を指しています。Adobe Readerは不正なソフトウェアを許容しているため、Adobe Readerで動作しますが、ファイルがISO-32000に違反しているため、iTextは誤解を招くような宛先について何も知らないため、少なくともSimpleNamedDEstination
はそれに関係する。
幸いにも、iTextはPDFのフードの下で深く進むことができる非常に多彩なライブラリです。この場合、レベルを1つだけ深くする必要があります。代わりにSimpleNamedDestination.getNamedDestination(reader, true)
、我々は次のようなアプローチを使用することができます。
HashMap<String, PdfObject> names = reader.getNamedDestinationFromNames();
for (Map.Entry<String, PdfObject> entry: names.entrySet()) {
System.out.print(entry.getKey());
System.out.print(": p");
PdfArray arr = (PdfArray)entry.getValue();
System.out.println(arr.getAsNumber(0).intValue() + 1);
}
reader.close();
このメソッドの出力は次のようになります。私たちは__WKANCHOR_2
をチェックすると
__WKANCHOR_w: p7
__WKANCHOR_y: p7
__WKANCHOR_2: p1
__WKANCHOR_4: p1
__WKANCHOR_16: p9
__WKANCHOR_14: p8
__WKANCHOR_18: p9
__WKANCHOR_1s: p13
__WKANCHOR_a: p2
__WKANCHOR_1q: p13
__WKANCHOR_1o: p12
__WKANCHOR_12: p8
__WKANCHOR_1m: p12
__WKANCHOR_e: p3
__WKANCHOR_10: p7
__WKANCHOR_1k: p12
__WKANCHOR_c: p3
__WKANCHOR_1i: p11
__WKANCHOR_i: p4
__WKANCHOR_8: p2
__WKANCHOR_g: p3
__WKANCHOR_1g: p11
__WKANCHOR_6: p1
__WKANCHOR_1e: p10
__WKANCHOR_m: p5
__WKANCHOR_1c: p10
__WKANCHOR_k: p4
__WKANCHOR_q: p5
__WKANCHOR_1a: p9
__WKANCHOR_o: p5
__WKANCHOR_u: p6
__WKANCHOR_s: p6
、私たちは私がチェックして、正しくページ1を指していることがわかり最終的なリンクは、名前が__WKANCHOR_1s
で、実際には13ページにリンクされています。
"ゴミがゴミに出る"問題の明確な例です。あなたのツールは、PDFのISO規格に違反しているPDFを生成します。その結果、間違ったことを理解しようとするのに時間が掛かります。しかし、さらに悪いことに、他人のせいで私は時間を失いました。
あなたの質問は「家事」の質問と言います。つまり、あなたはあなたの場所であなたの仕事をするためにスタックオーバーフローの読者に尋ねる。この質問は、あなたが試したことを示すことで* topic *の質問に変更できます。私は[Official documentation](http://developers.itextpdf.com)へのリンクとStack Overflowに関する以前の回答を回答しました。今は、あなたがそれらのポインタを試してみるのに時間を費やすのはあなた次第です。あなたの次のコメントが "私はそれを行う時間がない、ちょうど私にコードを与える"のように聞こえる場合、私はあなたが多くのダウン投票を得ると予測します。 –
PDFへのリンクはPDFへのリンクではありません。それはスクリーンショットへのリンクです。私はこれが専門的ではないことを理解していただければ幸いです。 PDF内のブックマークを調べて、明示的な送り先または名前付きの送り先で構成されているかどうかを調べることができます。あなたがPNGを共有しているなら、それはできません。開発者は、それを知っておくべきです(ただし、開発者ではないかもしれません)。 –
コメントに対するBrunoの感謝。私はブックマークでPDFを生成するとwkhtmltopdfを使用してPDFを生成しています。私がブックマークを(itextで)歩くと、ページ番号なしでアンカーへのリンクが付いたマップのリストが返されます。私の主な質問は、各アンカーのページ番号を取得する方法の1つです。 –