ページは文書で表示される順序とは異なる順序で作られます。ページグループはいくつかのページを作成し、ページラベルを提供します。最後のページを作成した後で、文書の最初に戻って、目次のためのページを挿入します。
/*
* Insert table of contents:
*
* Create some pages, assign labels to them and insert a table of contents at
* the beginning of the document.
*
* Pages are created in a different chronological order than the order in
* which they appear in the document. Using page groups create several pages
* and provide them with page labels. After creating the last page, go back
* to the start of the document and insert the pages for the table of contents.
*
* The table of contents is created twice, once using Textlines
* and once using Textflows.
*
* The entries on the table of contents pages can be clicked to jump to
* the corresponding page. This is implemented with matchboxes for the titles
* and with destinations.
*
* Required software: PDFlib/PDFlib+PDI/PPS 10
* Required data: none
*/
package com.pdflib.cookbook.pdflib.pagination;
import com.pdflib.pdflib;
import java.util.LinkedList;
import java.util.List;
import com.pdflib.PDFlibException;
public class insert_toc {
private static class toc_entry {
String text;
int page;
String destination;
}
public static void main(String argv[]) {
/* This is where the data files are. Adjust as necessary. */
String searchpath = "../input";
String outfile = "insert_toc.pdf";
String title = "Insert Table of Contents";
pdflib p = null;
int pageno, font, docsize = 0;
int exitcode = 0;
/*
* Using the "groups" option, define several page groups for the title
* (title), the table of contents (toc), the individual chapters (body),
* and the index (index). List them in the order they will appear in the
* document. Using the "labels" option, assign a page label to each page
* group.
*/
String optlist = "groups={title toc content index} "
+ "labels={{group=title prefix=title} "
+ "{group=toc prefix={toc } start=1 style=r} "
+ "{group=content start=1 style=D} "
+ "{group=index prefix={index } start=1 style=r}} "
+ "destination={type=fitwindow}";
try {
p = new pdflib();
List<toc_entry> toc_entries = new LinkedList<toc_entry>();
p.set_option("searchpath={" + searchpath + "}");
/*
* This means we must check return values of load_font() etc.
*/
p.set_option("errorpolicy=return");
if (p.begin_document(outfile, optlist) == -1)
throw new Exception("Error: " + p.get_errmsg());
p.set_info("Creator", "PDFlib Cookbook");
p.set_info("Title", title);
/* Create a page in the page group "title" */
p.begin_page_ext(0, 0, "width=a4.width height=a4.height group title");
docsize += 1;
p.fit_textline("Title", 50, 700,
"fontname=NotoSerif-Bold fontsize=36");
p.end_page_ext("");
/* Counter for all destinations */
int destno = 0;
/* Loop over all pages in the page group "content" */
String destname, headline;
for (pageno = 1; pageno <= 5; pageno++) {
p.begin_page_ext(0, 0, "width=a4.width height=a4.height group content");
docsize += 1;
headline = "Chapter " + pageno;
destname = "dest" + destno;
p.fit_textline(headline, 50, 700,
"fontname=NotoSerif-Bold "
+ " fontsize=36 matchbox={name=" + destname + "}");
p.end_page_ext("");
add_toc_entry_from_matchbox(p, toc_entries, pageno, headline,
destname);
destno += 1;
}
/* Insert two pages in the page group "index" */
p.begin_page_ext(0, 0, "width=a4.width height=a4.height group index");
docsize += 1;
headline = "Index I";
destname = "dest" + destno;
p.fit_textline(headline, 50, 700,
"fontname=NotoSerif-Bold "
+ " fontsize=36 matchbox={name=" + destname + "}");
add_toc_entry_from_matchbox(p, toc_entries, pageno, headline,
destname);
destno += 1;
pageno += 1;
p.end_page_ext("");
p.begin_page_ext(0, 0, "width=a4.width height=a4.height group index");
docsize += 1;
headline = "Index II";
destname = "dest" + destno;
p.fit_textline(headline, 50, 700,
"fontname=NotoSerif-Bold "
+ " fontsize=36 matchbox={name=" + destname + "}");
add_toc_entry_from_matchbox(p, toc_entries, pageno, headline,
destname);
destno += 1;
pageno += 1;
p.end_page_ext("");
int xoff = 50;
/*
* Insert two pages in the page group "toc" for a table of contents
*/
p.begin_page_ext(0, 0, "width=a4.width height=a4.height group toc");
docsize += 1;
p.fit_textline("Table of Contents I", xoff, 700,
"fontname=NotoSerif-Bold fontsize=36");
/* Create table of contents entries with textlines */
int toc_textboxwidth = 400, yoff = 20;
String textfontopts = "fontname=NotoSerif-Regular fontsize=14 ";
String textopts = textfontopts
+ " boxsize={" + toc_textboxwidth + " 30} "
+ "leader={alignment=right}";
String numopts = "fontname=NotoSerif-Bold fontsize=14 ";
int y = 660;
for (int i = 0; i < toc_entries.size(); i += 1, y -= yoff) {
toc_entry entry = toc_entries.get(i);
String text_entry_matchbox = "temb" + i;
/* Place the text line */
p.fit_textline(entry.text, xoff, y, textopts
+ " matchbox={name=" + text_entry_matchbox + "}");
String num_entry_matchbox = "nummb" + i;
p.fit_textline(Integer.toString(entry.page),
xoff + toc_textboxwidth, y, numopts + " matchbox={name="
+ num_entry_matchbox + "}");
/*
* Create link annotations for both matchboxes
*/
p.create_annotation(0, 0, 0, 0, "Link",
"usematchbox={" + text_entry_matchbox + "} "
+ "destname={" + entry.destination
+ "} linewidth=0");
p.create_annotation(0, 0, 0, 0, "Link",
"usematchbox={" + num_entry_matchbox + "} "
+ "destname={" + entry.destination
+ "} linewidth=0");
}
y -= yoff;
p.fit_textline("Click on TOC entry to jump to page", xoff, y,
textfontopts);
p.end_page_ext("");
/* Create table of contents with textflow */
String tf_optlist = "fontname=NotoSerif-Regular fontsize=12 "
+ "leading=160% ruler=100% "
+ "hortabmethod=ruler tabalignment=right";
StringBuilder toc_tf_text = new StringBuilder();
/*
* Build the text for the whole textflow containing the TOC entries.
*/
String tf_entry_matchbox_name = "tfentmb";
for (int i = 0; i < toc_entries.size(); i++) {
toc_entry entry = toc_entries.get(i);
String tf_entry_matchbox = tf_entry_matchbox_name + i;
String entry_text = "<alignment=left><matchbox={name="
+ tf_entry_matchbox + "}>" + entry.text
+ "<leader={alignment={grid}}>\t" + entry.page
+ "<matchbox=end><nextline>";
toc_tf_text.append(entry_text);
}
toc_tf_text.append("<nextline>Click on TOC entry to jump to page");
int toc_tf = p.create_textflow(toc_tf_text.toString(), tf_optlist);
if (toc_tf == -1)
throw new Exception("Error: " + p.get_errmsg());
p.begin_page_ext(0, 0, "width=a4.width height=a4.height group toc");
docsize += 1;
p.fit_textline("Table of Contents II", xoff, 700,
"fontname=NotoSerif-Bold fontsize=36");
p.fit_textline("for a Document of " + docsize + " Pages.", 50, 650,
"fontname=NotoSerif-Bold fontsize=24");
/* Error handling and overflow handling omitted here */
p.fit_textflow(toc_tf, xoff, xoff, xoff + toc_textboxwidth, 600,
"");
/* Create Link annotations for matchboxes */
for (int i = 0; i < toc_entries.size(); i++) {
String tf_entry_matchbox = tf_entry_matchbox_name + i;
toc_entry entry = toc_entries.get(i);
p.create_annotation(0, 0, 0, 0, "Link",
"usematchbox={" + tf_entry_matchbox + "} "
+ "destname={" + entry.destination
+ "} linewidth=0");
}
p.end_page_ext("");
p.end_document("");
}
catch (PDFlibException e) {
System.err.println("PDFlib exception occurred:");
System.err.println("[" + e.get_errnum() + "] " + e.get_apiname()
+ ": " + e.get_errmsg());
exitcode = 1;
}
catch (Exception e) {
System.err.println(e);
exitcode = 1;
}
finally {
if (p != null) {
p.delete();
}
System.exit(exitcode);
}
}
private static void add_toc_entry_from_matchbox(pdflib p,
List<toc_entry> toc_entries, int pageno, String headline,
String matchboxname) throws PDFlibException {
/* Retrieve y coordinate of upper edge of matchbox. */
double top = p.info_matchbox(matchboxname, 1, "y4");
p.add_nameddest(matchboxname, "top=" + top);
/* Create an entry in the list of TOC entries. */
toc_entry entry = new toc_entry();
entry.text = headline;
entry.page = pageno;
entry.destination = matchboxname;
toc_entries.add(entry);
}
}