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

com.vectorprint.report.itext.TocOutputStream Maven / Gradle / Ivy

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