gutenberg.itext.TableOfContentsPostProcessor Maven / Gradle / Ivy
package gutenberg.itext;
import com.itextpdf.text.Chunk;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.draw.LineSeparator;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* @author @aloyer
*/
public class TableOfContentsPostProcessor implements PostProcessor {
private static final String TOC_ENTRY_FONT = "tableOfContents-entry-font";
private Logger log = LoggerFactory.getLogger(TableOfContentsPostProcessor.class);
private final HeaderFooter headerFooter;
public TableOfContentsPostProcessor(HeaderFooter headerFooter) {
this.headerFooter = headerFooter;
}
@Override
public void postProcess(ITextContext context, File fileIn, File fileOut) {
FileInputStream in = null;
FileOutputStream out = null;
try {
in = new FileInputStream(fileIn);
out = new FileOutputStream(fileOut);
PageNumber pageNumber = context.pageNumber();
int startPage = pageNumber.lookupFrontMatterLastPage();
ColumnText ct = generateTableOfContent(context);
pageNumber.continueFrontMatter();
PdfReader reader = new PdfReader(in);
Rectangle pageSize = reader.getPageSize(1);
PdfStamper stamper = new PdfStamper(reader, out);
while (true) {
stamper.insertPage(++startPage, pageSize);
PdfContentByte under = stamper.getUnderContent(startPage);
pageNumber.notifyPageChange();
headerFooter.drawFooter(under, pageNumber.pageInfos());
PdfContentByte canvas = stamper.getOverContent(startPage);
ct.setCanvas(canvas);
ct.setSimpleColumn(36, 36, 559, 770);
if (!ColumnText.hasMoreText(ct.go()))
break;
}
stamper.close();
} catch (FileNotFoundException e) {
log.error("Unable to reopen temporary generated file ({})", fileIn, e);
} catch (DocumentException e) {
log.error("Error during report post-processing from: {}, to: {}", fileIn, fileOut, e);
} catch (IOException e) {
log.error("Error during report post-processing from: {}, to: {}", fileIn, fileOut, e);
} finally {
IOUtils.closeQuietly(out);
IOUtils.closeQuietly(in);
}
}
public ColumnText generateTableOfContent(ITextContext context) {
ColumnText ct = new ColumnText(null);
Styles styles = context.styles();
Chunk CONNECT = connectChunk(styles);
Paragraph paragraph = new Paragraph();
paragraph.setSpacingBefore(20.0f); // first paragraph only
ct.addElement(new Paragraph("Table of content", styles.sectionTitleFontForLevel(1)));
ct.addElement(new Paragraph(""));
Font entryFont = styles.getFontOrDefault(TOC_ENTRY_FONT);
TableOfContents tableOfContents = context.tableOfContents();
for (TableOfContents.Entry entry : tableOfContents.getEntries()) {
//if (entry.isExtra())
// continue;
Chunk chunk = new Chunk(entry.getText(), entryFont);
paragraph.add(chunk);
paragraph.add(CONNECT);
paragraph.add(new Chunk("" + entry.getFormattedPageNumber(), entryFont));
float indent = 10.0f * entry.getLevel();
paragraph.setIndentationLeft(indent);
ct.addElement(paragraph);
paragraph = new Paragraph();
}
return ct;
}
private Chunk connectChunk(Styles styles) {
return new Chunk(new LineSeparator(0.5f, 95, styles.defaultColor(), Element.ALIGN_CENTER, -.5f));
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy