
com.vectorprint.report.itext.TocOutputStream Maven / Gradle / Ivy
package com.vectorprint.report.itext;
/*
* #%L
* ConfigurableReports
* %%
* Copyright (C) 2014 - 2016 VectorPrint
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
* #L%
*/
import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Image;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.Section;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.SimpleBookmark;
import com.vectorprint.VectorPrintException;
import com.vectorprint.VectorPrintRuntimeException;
import com.vectorprint.configuration.EnhancedMap;
import com.vectorprint.report.ReportConstants;
import com.vectorprint.report.itext.debug.DebugHelper;
import com.vectorprint.report.itext.style.DefaultStylerFactory;
import com.vectorprint.report.itext.style.DocumentStyler;
import com.vectorprint.report.itext.style.StyleHelper;
import com.vectorprint.report.itext.style.StylerFactory;
import com.vectorprint.report.itext.style.StylerFactoryHelper;
import com.vectorprint.report.itext.style.stylers.DocumentSettings;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/**
* Responsible for printing a table of contents according to settings in {@link DocumentSettings}.
*
* @author Eduard Drenth at VectorPrint.nl
*/
class TocOutputStream extends AbstractTwoPassStream {
private final BaseReportGenerator outer;
public TocOutputStream(OutputStream out, int bufferSize, final BaseReportGenerator outer) throws IOException {
super(out, bufferSize);
this.outer = outer;
}
@Override
public void secondPass(InputStream firstPass, OutputStream orig) throws IOException {
PdfReader reader = null;
VectorPrintDocument vpd = (VectorPrintDocument) outer.getDocument();
try {
reader = new PdfReader(firstPass);
prepareToc();
// init fresh components for second pass styling
StylerFactory _stylerFactory = outer.getStylerFactory().getClass().newInstance();
StylerFactoryHelper.SETTINGS_ANNOTATION_PROCESSOR.initSettings(_stylerFactory, outer.getSettings());
_stylerFactory.setLayerManager(outer.getElementProducer());
_stylerFactory.setImageLoader(outer.getElementProducer());
outer.getStyleHelper().setStylerFactory(_stylerFactory);
EventHelper event = outer.getEventHelper().getClass().newInstance();
event.setItextStylerFactory(_stylerFactory);
event.setElementProvider(outer.getElementProducer());
((DefaultElementProducer) outer.getElementProducer()).setPh(event);
Document d = new VectorPrintDocument(event, _stylerFactory, outer.getStyleHelper());
PdfWriter w = PdfWriter.getInstance(d, orig);
w.setPageEvent(event);
outer.getStyleHelper().setVpd((VectorPrintDocument) d);
_stylerFactory.setDocument(d, w);
DocumentStyler ds = _stylerFactory.getDocumentStyler();
outer.getStyleHelper().style(d, null, StyleHelper.toCollection(ds));
d.open();
ds.styleAfterOpen(d, null);
List outline = SimpleBookmark.getBookmark(reader);
if (!ds.getValue(DocumentSettings.TOCAPPEND, Boolean.class)) {
printToc(d, w, vpd);
if (outline != null) {
int cur = w.getCurrentPageNumber();
SimpleBookmark.shiftPageNumbers(outline, cur, null);
}
d.newPage();
}
outer.getSettings().put(ReportConstants.DEBUG, Boolean.FALSE.toString());
for (int p = 1; p <= reader.getNumberOfPages(); p++) {
Image page = Image.getInstance(w.getImportedPage(reader, p));
page.setAbsolutePosition(0, 0);
d.setPageSize(page);
d.newPage();
Chunk i = new Chunk(" ");
if (vpd.getToc().containsKey(p)) {
Section s = null;
for (Map.Entry> e : vpd.getToc().entrySet()) {
if (e.getKey() == p) {
s = e.getValue().get(0);
break;
}
}
i.setLocalDestination(s.getTitle().getContent());
}
d.add(i);
w.getDirectContent().addImage(page);
w.freeReader(reader);
}
if (_stylerFactory.getDocumentStyler().getValue(DocumentSettings.TOCAPPEND, Boolean.class)) {
printToc(d, w, vpd);
}
w.setOutlines(outline);
if (outer.isWasDebug()) {
event.setLastPage(outer.getWriter().getCurrentPageNumber());
d.setPageSize(new Rectangle(ItextHelper.mmToPts(297), ItextHelper.mmToPts(210)));
d.setMargins(5, 5, 5, 5);
d.newPage();
outer.getSettings().put(ReportConstants.DEBUG, Boolean.TRUE.toString());
event.setDebugHereAfter(true);
DebugHelper.appendDebugInfo(w, d, outer.getSettings(), _stylerFactory);
}
d.close();
} catch (VectorPrintException | DocumentException | InstantiationException | IllegalAccessException ex) {
throw new VectorPrintRuntimeException(ex);
} finally {
if (reader != null) {
reader.close();
}
}
}
private void prepareToc() throws VectorPrintException {
DocumentStyler ds = outer.getStylerFactory().getDocumentStyler();
EnhancedMap settings = outer.getSettings();
if (!settings.containsKey(DocumentSettings.TOCTITLESTYLEKEY)) {
settings.put(DocumentSettings.TOCTITLESTYLEKEY, DocumentSettings.TOCTITLESTYLE);
}
if (!settings.containsKey(DocumentSettings.TOCNRSTYLEKEY)) {
settings.put(DocumentSettings.TOCNRSTYLEKEY, DocumentSettings.TOCNRSTYLE);
}
if (!settings.containsKey(DocumentSettings.TOCHEADERSTYLEKEY)) {
settings.put(DocumentSettings.TOCHEADERSTYLEKEY, DocumentSettings.TOCHEADER);
}
if (!settings.containsKey(DocumentSettings.TOCCAPTIONKEY)) {
settings.put(DocumentSettings.TOCCAPTIONKEY, DocumentSettings.TOCCAPTION);
}
settings.remove(DefaultStylerFactory.PRESTYLERS);
settings.remove(DefaultStylerFactory.POSTSTYLERS);
settings.remove(DefaultStylerFactory.PAGESTYLERS);
settings.put(ReportConstants.PRINTFOOTER, "false");
if (!settings.containsKey(DocumentSettings.TOCTABLEKEY)) {
float tot = ItextHelper.ptsToMm(outer.getDocument().getPageSize().getWidth() - outer.getDocument().leftMargin() - outer.getDocument().rightMargin());
settings.put(DocumentSettings.TOCTABLEKEY, new String[]{"Table(columns=2,widths=" + (Math.round(tot * ds.getValue(DocumentSettings.TOCLEFTWIDTH, Float.class))) + '|' + (Math.round(tot * ds.getValue(DocumentSettings.TOCRIGHTWIDTH, Float.class))) + ')', "AddCell(data=Table of Contents,styleclass=toccaption)", "AddCell(data=title,styleclass=tocheader)", "AddCell(data=page,styleclass=tocheader)"});
}
}
private void printToc(Document d, PdfWriter w, VectorPrintDocument vpd) throws VectorPrintException, InstantiationException, IllegalAccessException, DocumentException {
DocumentStyler ds = outer.getStylerFactory().getDocumentStyler();
if (ds.getValue(DocumentSettings.TOCAPPEND, Boolean.class)) {
d.add(Chunk.NEXTPAGE);
}
if (outer.isWasDebug()) {
outer.getSettings().put(ReportConstants.DEBUG, Boolean.TRUE.toString());
PdfContentByte canvas = w.getDirectContent();
outer.startLayerInGroup(ReportConstants.DEBUG, canvas);
BaseFont bf = DebugHelper.debugFont(canvas, outer.getSettings());
canvas.showTextAligned(Element.ALIGN_RIGHT, "FOR DEBUG INFO IN THE DOCUMENT TURN OFF TOC (-DocumentSettings.toc=false)", d.right(), d.getPageSize().getHeight() - ItextHelper.getTextHeight("F", bf, 8), 0);
canvas.endLayer();
}
ElementProducer ep = outer.getElementProducer();
StylerFactory sf = outer.getStylerFactory();
PdfPTable tocTable = ep.createElement(null, PdfPTable.class, sf.getStylers(DocumentSettings.TOCTABLEKEY));
for (Map.Entry> e : vpd.getToc().entrySet()) {
String link = null;
for (Section s : e.getValue()) {
if (ds.isParameterSet(DocumentSettings.TOCMAXDEPTH) && ds.getValue(DocumentSettings.TOCMAXDEPTH, Integer.class) < s.getDepth()) {
continue;
}
if (link == null) {
link = s.getTitle().getContent();
}
Chunk c = ep.createElement(s.getTitle().getContent(), Chunk.class, sf.getStylers(DocumentSettings.TOCTITLESTYLEKEY));
if (ds.getValue(DocumentSettings.TOCDOTS, Boolean.class)) {
float tw = ItextHelper.getTextWidth(c);
float cw = tocTable.getAbsoluteWidths()[0];
float dw = ItextHelper.getTextWidth(ep.createElement(".", Chunk.class, sf.getStylers(DocumentSettings.TOCTITLESTYLEKEY))) * 1.5f;
int numDots = (int) ((cw > tw) ? (cw - tw) / dw : 0);
char[] dots = new char[numDots];
Arrays.fill(dots, '.');
c = ep.createElement(s.getTitle().getContent() + " " + String.valueOf(dots), Chunk.class, sf.getStylers(DocumentSettings.TOCTITLESTYLEKEY));
}
c.setLocalGoto(link);
tocTable.addCell(ep.createElement(c, PdfPCell.class, sf.getStylers(DocumentSettings.TOCTITLESTYLEKEY)));
c = ep.createElement(e.getKey(), Chunk.class, sf.getStylers(DocumentSettings.TOCNRSTYLEKEY));
c.setLocalGoto(link);
tocTable.addCell(ep.createElement(c, PdfPCell.class, sf.getStylers(DocumentSettings.TOCNRSTYLEKEY)));
}
}
d.add(tocTable);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy