All Downloads are FREE. Search and download functionalities are using the official Maven repository.

gutenberg.itext.TableOfContentsPostProcessor Maven / Gradle / Ivy

There is a newer version: 1.3.0
Show newest version
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