Package cli_fmw.report.implemenatation

Source Code of cli_fmw.report.implemenatation.JasperReportBuilder

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

package cli_fmw.report.implemenatation;

import cli_fmw.report.ReportPreferences;
import cli_fmw.report.AlignmentType;
import cli_fmw.report.ExtraField;
import cli_fmw.report.PageOptions;
import cli_fmw.report.TableReportOptions;
import cli_fmw.report.ReporterFactory;
import java.awt.Color;
import java.awt.Font;
import java.awt.font.FontRenderContext;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import javax.swing.table.TableModel;
import net.sf.jasperreports.engine.JRDefaultStyleProvider;
import net.sf.jasperreports.engine.JRElement;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRExpression;
import net.sf.jasperreports.engine.JRLineBox;
import net.sf.jasperreports.engine.JRStyle;
import net.sf.jasperreports.engine.JRStyleContainer;
import net.sf.jasperreports.engine.JRTextElement;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.base.JRBaseFont;
import net.sf.jasperreports.engine.design.JRDesignBand;
import net.sf.jasperreports.engine.design.JRDesignExpression;
import net.sf.jasperreports.engine.design.JRDesignFrame;
import net.sf.jasperreports.engine.design.JRDesignParameter;
import net.sf.jasperreports.engine.design.JRDesignStyle;
import net.sf.jasperreports.engine.design.JRDesignTextField;
import net.sf.jasperreports.engine.design.JasperDesign;
import net.sf.jasperreports.engine.export.TextRenderer;
import net.sf.jasperreports.engine.util.JRFontUtil;

/**
* Клас отвечает за динамическую генерацию отчета.
*
* краткая справка по терминам:
* Параметр отчета 1) - В jasper report пред использование внешнего параметра, его надо описать,
* описание включает в себя тип параметра (Имя его класса), и его имя.
*    При автогенерации тип всегда String
* Параметр отчета 2) - обект типа Map.Entry, состоит из имени параметра, его ключа
*      (типа java.​lang.String), и собственно занчения. Обработка занчений приметивна,
*      и сводится к приведению их к строке с помощью функции ReporterFactory.convertDataToString.
*      За исключением случаев когда в качестве обьекта передается ExtraFields
* Поле отчета -  обект всавленный в отчет для отображения содержимого параметра.
* Тексьовое поле - СМ Поле отчета.
* Поле данных - В jasper report прараметры каждого повторяющегося элемента отчета,
*        должны быть предворитльно описаны, описание называются поле.
* Элемент - одна ячейка таблицы.
* @author finder
*/
public class JasperReportBuilder implements JasperBuilder{
  public static String      AUTO_GENERATED_PROPERTY = "infotech.is_autogenerated";
  /**
   * Строка которая будет напечатанна в заголовке отчета.
   */
  String              title;
  /**
   * Общие опции генерации отчета
   */
  PageOptions            options;
  /**
   * список дополнительны полей которые будут размещенны сверху отчета.
   * элементы типа ExtraFields будут обработтаны отдельно, для преврощение всех
   * остальных в строку будет вызванна ReporterFactory.convertDataToString
   */
  Collection<Map.Entry<String, Object>>topExtraFields;
  /**
   * список дополнительны полей которые будут размещенны снизу отчета.
   */
  Collection<Map.Entry<String, Object>>bottomExtraFields;
 
  /**
   * Ссылка на итерфейс изменяющий геренацию отчета, для коррекции внешнего вида,
   * в процессе построения шаблона отчета, этот интерфейс прифодится к его наследжникам,
   * и вызываются соотведствующие методы обработки.
   */
  JasperReportBuilderCustomizer  customizer;
   
  /**
   * Шаблон создаваемого в данный момент отчета.
   */
  JasperDesign          targetDesting;
 
  /**
   * Обычный слиль отчета, им например ресуются поля.
   * Все остальные слили базируются на обычном
   */
  JRDesignStyle          normalStyle;
  /**
   * Стиль которым ресуетс заголовок отчета. Обычный + увеличенный в двое размер шрифта.
   */
  JRDesignStyle          headerStyle;
  /**
   * Банд содержит элементы заголовка отчета. (Строку заголовка, и вегхние поля)
   * При добавлении элементов они начинаю добовлятся начиная с позиции равной
   * высоте банда, после добавлении банд растягивается чтобы вместить новые элементы.
   */
  JRDesignBand          reportHeaderBand;
  /**
   * Банд содержит заголовок таблицы высота как у элемента таблицы
   */
  JRDesignBand          colomnHeaderBand;
  /**
   * Банд с элементами таблицы
   */
  JRDesignBand          detalsBand;
  /**
   * Банд находящий внизу последней страницы отчета, содержит
   */
  JRDesignBand          reportFooterBand;
  /**
   * Шрифт максимально близкий к шрифту слитиля Normal
   */
  Font              normalJavaFont;
  /**
   * Данне контекста шрифта которым будет рейдится отчет
   */
  FontRenderContext        frontRenderContext = TextRenderer.LINE_BREAK_FONT_RENDER_CONTEXT;
 
  JasperDetailBuilder        builder;
 
  /**
   * Ширина отчета в логических пикселях
   */
  int                destingWidth;
   
  /**
   * Основной конструктор, созает построитель отчета. Для каждого набора данных нужно создать свой построитель.
   * Все параметры могут быть null
   * @param title - Строка которая будет напечатанна в заголовке отчета
   * @param options - Общие опции генерации отчета
   * @param topExtraFields - список дополнительны полей которые будут размещенны сверху отчета.
   *            элементы типа ExtraFields будут обработтаны отдельно, для преврощение всех
   *            остальных в строку будет вызванна ReporterFactory.convertDataToString
   * @param bottomExtraFields - элеметы которые будут напечатанны снизу отчета
   * @param table - ссылка на модель таблицы, если отчет содержит таблицу
   */
  public JasperReportBuilder(String title, PageOptions options, Collection<Entry<String, Object>> topExtraFields, Collection<Entry<String, Object>> bottomExtraFields, JasperDetailBuilder builder) {
    this.title = title;
    if (options == null) {
      throw new IllegalArgumentException("options cannot be null");
    }
    this.options = options;
    this.topExtraFields = topExtraFields;
    this.bottomExtraFields = bottomExtraFields;
    this.builder = builder;
  }
 
  /**
   * Строит шаблоннон отчета, на на основе пустого наблона, и переданных в конструктор данных.
   * @return свежепостроеный отчет.
   * @throws net.sf.jasperreports.engine.JRException - если построение отчета навернулось изза невалидных данны,
   *                  нефатально, но генератор после в невалидном состоянии.
   */
 
  public JasperReport buildReport() throws JRException{
    initDesting();
   
    double      pos = 0;
    if (reportHeaderBand != null) {
      pos = reportHeaderBand.getHeight();
    }
    if (title != null) {
      pos = createTitle(pos, reportHeaderBand, title);
    }
    if (topExtraFields != null) {
      pos = createReportFields(pos, reportHeaderBand, topExtraFields);
    }
    if (reportHeaderBand != null) {
      reportHeaderBand.setHeight((int) Math.round(pos));
    }
   
    if (builder != null) {
      builder.buildDetails(this, customizer);
    }
   
    if (reportFooterBand != null) {
      pos = reportFooterBand.getHeight();
    }
    if (bottomExtraFields != null) {
      pos = createReportFields(pos, reportFooterBand, bottomExtraFields);
    }
    if (reportFooterBand != null) {
      reportFooterBand.setHeight((int) Math.round(pos));
    }
   
    //JRXmlWriter.writeReport(targetDesting, "/home/vip/test.jrxml", "UTF-8");
    return JasperCompileManager.compileReport(targetDesting);
  }
 
  /**
   * Устанавливает кастомизатор для генератора, кастомизатор работает как обработчик раличных событитй,
   * меняет процес построениея шаблона отчета.
   * @param costomizer - интерфейс класса меняющего построение отчета.
   *            В случае если класс наследует любой из потомков
   *            JasperReportBuilderCustomizer то в процессе построения отчета
   *            интерфейс будет автоматичеки приведен к этому потомку
   *            и вызванна соотведствующия функция обработчик.
   */

  public void applyCostumizer(JasperReportBuilderCustomizer costomizer){
    this.customizer = costomizer;
    costomizer.customizerBuilder(this);
  }

  /**
   *  Возвращает ширину отчета в логических пикселях
   * @return
   */
 
  @Override
  public int getDestingWidth() {
    return destingWidth;
  }   
 
  /**
   * Взвращает длинну линии, отпечатонной стилем Normal.
   * @param line
   * @return
   */
 
  double getLineLength(String line){
    return normalJavaFont.getStringBounds(line, frontRenderContext).getWidth();
  }
 
 
  /**
   * Взвращает длинну строки, отпечатонной стилем Normal.
   * @param line
   * @return
   */
 
  @Override
  public double getStringLength(String str){
    double      target = 0;
    int        lastPos = 0;
    do{
      int        newPos = str.indexOf('\n', lastPos);
      if (newPos < 0) {
        newPos = str.length();
      }
      String      line = str.substring(lastPos, newPos);
      target = Math.max(target, getLineLength(line));
      lastPos = newPos + 1;
    }
    while (lastPos < str.length());
    return target;
  }

  /**
   * Возаращает высоту поля вмещающего одну строку текста.
   * @return
   */
 
  @Override
  public double getFieldHeigth(){
    double      target = normalJavaFont.getMaxCharBounds(frontRenderContext).getHeight();
    JRLineBox box = normalStyle.getLineBox();
    target += box.getTopPadding();
    target += box.getBottomPadding();
    target += box.getTopPen().getLineWidth();
    return (int) Math.round(target);
  }
 
  /**
   * Возврашает минимальный размер поля по горизонтали, который
   * вмещает в себя эту строку без переносов.
   * @param line
   * @return
   */
 
  @Override
  public double getFieldLenght(String line){
    double    target = getStringLength(line);
    JRLineBox  box = normalStyle.getLineBox();
    target += box.getLeftPadding();
    target += box.getRightPadding();
    target += box.getLeftPen().getLineWidth();
    target += 1;
    return target;
  }
 
  /**
   * Возвращает высоту заголовка отчета.
   * @return
   */
 
  int getHeaderHeight(){
    return (int)Math.round(getFieldHeigth() + 3);
  }

  @Override
  public JRDesignBand getColomnHeaderBand() {
    if (colomnHeaderBand == null){
      colomnHeaderBand = new JRDesignBand();
      getTargetDesting().setColumnHeader(colomnHeaderBand);
    }
    return colomnHeaderBand;
  }

  @Override
  public JRDesignBand getDetalsBand() {
    if (detalsBand == null){
      detalsBand = new JRDesignBand();
      getTargetDesting().setDetail(detalsBand);
    }
    return detalsBand;
  }

  @Override
  public JRDesignStyle getNormalStyle() {
    return normalStyle;
  }

  @Override
  public JasperDesign getTargetDesting() {
    return targetDesting;
  }
 
 
 
  /**
   * Создает новый пустой шаблон отчета, также инициализирует ему все стили,
   * банды, и тп.
   * @throws net.sf.jasperreports.engine.JRException
   */
 
  void initDesting() throws JRException{
    targetDesting = new JasperDesign();
    targetDesting.setWhenNoDataType(JasperDesign.WHEN_NO_DATA_TYPE_ALL_SECTIONS_NO_DETAIL);     
    targetDesting.setName("Auto Generated Report");
    targetDesting.setProperty(AUTO_GENERATED_PROPERTY, Boolean.toString(true));
    initStyles();
    initBands();
    initDestingSizes();
  }
 
  /**
   * Инициализирует размеры отчета в соотведствии с текущими параметрами отчета (preferences)
   */
 
  void initDestingSizes(){
    if (options.getOrentation() == TableReportOptions.PageOrentation.vertical){
      targetDesting.setOrientation(JasperDesign.ORIENTATION_PORTRAIT);
    }
    else if (options.getOrentation() == TableReportOptions.PageOrentation.horizontal){
      targetDesting.setOrientation(JasperDesign.ORIENTATION_LANDSCAPE);
    }
    else {
      throw new IllegalArgumentException("PageOptions.getOrentation() has uncnown value");
    }
    targetDesting.setPageHeight(options.reportHeight);
    targetDesting.setPageWidth(options.reportWidht);
   
    targetDesting.setTopMargin(options.topMargin);
    targetDesting.setBottomMargin(options.bottomMargin);
    targetDesting.setLeftMargin(options.leftMargin);
    targetDesting.setRightMargin(options.rightMargin);
   
    // Устанавливаю переменную класса с размером отчета
    destingWidth = targetDesting.getPageWidth()
        - targetDesting.getLeftMargin()
        - targetDesting.getRightMargin();
   
    targetDesting.setColumnWidth(destingWidth);
    targetDesting.setColumnSpacing(0);
    targetDesting.setPrintOrder(JasperDesign.PRINT_ORDER_VERTICAL);
  }
 
  /**
   * инициализирует все стили отчета, также создает в соодтведствии со стилем Normal
   * стандартный Java шриф, c помощью которого вычесляются размеры строк
   * @throws net.sf.jasperreports.engine.JRException
   */
 
  @SuppressWarnings("unchecked")
  void initStyles() throws JRException{
    normalStyle = new JRDesignStyle();
    normalStyle.setName("Normal");
    normalStyle.setDefault(true);
    normalStyle.setForecolor(new Color(0, 0, 0));
    normalStyle.setBlankWhenNull(true);
    normalStyle.setFontSize(options.textSize);
    normalStyle.setMode(JRElement.MODE_TRANSPARENT);
    normalStyle.getLineBox().setPadding(options.padding);
        normalStyle.setPdfEmbedded(true);
        normalStyle.setPdfEncoding("Cp1251");
        normalStyle.setPdfFontName("/usr/share/fonts/truetype/freefont/lucon.ttf");
    targetDesting.addStyle(normalStyle);
    targetDesting.setDefaultStyle(normalStyle);
    headerStyle = new JRDesignStyle();
    headerStyle.setName("Header");
    headerStyle.setDefault(false);
    headerStyle.setParentStyle(normalStyle);
        headerStyle.setBold(true);
    headerStyle.setFontSize(options.textSize + 2);
    headerStyle.setHorizontalAlignment(JRTextElement.HORIZONTAL_ALIGN_CENTER);
       
    targetDesting.addStyle(headerStyle);
   
    JRStyleContainer  tmpContener = new JRStyleContainer() {

      @Override
      public JRDefaultStyleProvider getDefaultStyleProvider() {
        return null;
      }

      @Override
      public JRStyle getStyle() {
        return normalStyle;
      }

      @Override
      public String getStyleNameReference() {
        return normalStyle.getName();
      }
    };
    JRBaseFont      font = new JRBaseFont(null, null, tmpContener, null);
    Map          attributes = new HashMap();
    JRFontUtil.getAttributes(attributes, font, Locale.getDefault());
    //JRStyledText    text = new JRStyledText();
    normalJavaFont = new Font(attributes);
  }
 
  /**
   * Инициализирует бандов отчета
   */
 
  void initBands(){
    if (topExtraFields != null || title != null){
      reportHeaderBand = new JRDesignBand();
      reportHeaderBand.setHeight(0);
      reportHeaderBand.setSplitAllowed(true);
      targetDesting.setTitle(reportHeaderBand);
    }
    if (bottomExtraFields != null){
      reportFooterBand = new JRDesignBand();
      reportFooterBand.setHeight(0);
      reportFooterBand.setSplitAllowed(true);
      //reportFooterBand.
      //targetDesting.set
      targetDesting.setSummary(reportFooterBand);
    }
  }
   
 
  /**
   * Создает JRExpression которое содержит строку в качестве формулы переданную строку,
   * результатом вачесления формулы должна быть строка
   * @param str - строка содержащая фрмулу. Если null то заначением выражения будет пустая строка.
   * @return - JRDesignExpression
   */
 
  @Override
  public JRDesignExpression createExpression(String str){
    JRDesignExpression    expression = new JRDesignExpression();
    expression.setValueClass(java.lang.String.class);
    if (str == null) {
      str = "\"\"";
    }
    expression.setText(str);
    return expression;
  }
 
  /**
   * Создает JRExpression - результатом вычесления которого будет переданная строка
   * @param str - поростая строка текста
   * @return - JRDesignExpression
   */
 
  @Override
  public JRDesignExpression createStringExpression(String str){
    if (str == null) {
      str = "";
    }
    str = "\"" + screenString(str) + "\"";
    return createExpression(str);
  }
 
  /**
   * Создает JRDesignExpression на основе выражения результатом вычеслеия которого будет тип boolean.
   * @param str - строка содержащая выражение, результатом вычесления которого будет тип boolean
   * @return JRDesignExpression
   */
 
  @Override
  public JRDesignExpression createBooleanExpression(String str){
    if (str == null) {
      throw new IllegalArgumentException("Пустая строка выражения");
    }
    JRDesignExpression exp = new JRDesignExpression();
    exp.setValueClass(Boolean.class);
    exp.setText("new Boolean(" + str + ")")
    return exp;
  }
 
  /**
   * Создает елкмент "текстовое поле" с заданными параметрами.
   * @param type - тип текстового поля, от типа поля зависит его стиль,
   *      а так же некоторые особенности форматирования.
   * @param x - горизонтальная координата текстового поля.
   * @param y - вертикальная координата текстового поля.
   * @param w - высота поля
   * @param h - высота поля
   * @param fieldExpression - выродение которе должно отображать поле
   * @return - текстовое поле с заданными параметрами
   */
 
  @Override
  public JRDesignTextField createItem(FieldTypes type, int x, int y, int w, int h, JRExpression fieldExpression){
    JRDesignTextField      textField = new JRDesignTextField();
    textField.setX(x);
    textField.setY(y);
    textField.setWidth(w);
    textField.setHeight(h);
    textField.setExpression(fieldExpression);
    textField.setBlankWhenNull(true);
    textField.setPositionType(JRDesignTextField.POSITION_TYPE_FLOAT);
    textField.setStretchWithOverflow(true);
    switch (type){
      case header:
        textField.setStyle(headerStyle);
        break;
      case firstPrage:
        textField.setStyle(normalStyle);
        break;
    }
    return textField;
  }
 
  public static String screenString(String str){
    StringBuilder      builder = new StringBuilder(str.length() << 1);
    for (int i = 0; i < str.length(); i++) {
      char ch = str.charAt(i);
      switch (ch){
        case '\n':
          builder.append("\\n");
          break;
        case '\r':
          builder.append("\\r");
          break;
        case '\\':
        case '\"':
        case '\'':
          builder.append('\\');
          builder.append(ch);
          break;
        default:
          builder.append(ch);
      }
    }
    return builder.toString();
  }
 
  /**
   * Содает выражение результатом которого является имя поля отображаетмое пльзователю
   * (взятое из ExtraField)
   * @param val - значение типа ExtraField
   * @return - строка с выражением добавленн
   */
  String expressionFieldName(ExtraField val, boolean withPluss){
    if (val != null && val.fieldName != null) {
      if (withPluss) {
        return "\"" + screenString(val.fieldName) + " \" + ";
      }
      else {
        return "\"" + screenString(val.fieldName) + "\"";
      }
    }   
    return ""
  }
 
  /**
   * Создает выражение, результатом которого является заначение параметра,
   * если параметр null, то создается статичная строка.
   * @param param - уже созданный параметр отчета
   * @param val - занчение поля, нужно если параметр null
   * @return - строка с с формулой
   */
 
  String expressionParamNullCheck(JRDesignParameter param, Object val){
    if (param == null){
      if (val != null) {
        return "\"" + screenString(ReporterFactory.convertDataToString(val)) + "\"";
      }
      else {
        return "\"\"";
      }
    }
    return "($P{" + param.getName() + "} == null? \"\": $P{" + param.getName() + "})" ;
  }
 
  /**
   * Возвращае выражение результатом которого является суффикс поля взятый из ExtraField
   * @param val - значение типа ExtraField
   * @return - строка с выражением, добавлени которой к выражению с данными
   *      приведет к добавлению суфикса
   */
 
  String expressionFieldSufix(ExtraField val){
    if (val != null && val.fieldSufix != null && val.fieldSufix.length() > 0) {
      return " + \"" + screenString(val.fieldSufix) + "\"";
    }   
    return "";
  }
 
  /**
   * Созадет выражение, результатом вычесления которого будут данные поля,
   * в зависимости от типа поля.
   * @param param - параметр с исходными данными, если null то поле будет статическим.
   * @param val - заначение
   * @return - стррковое выражение, результатом вычесления которго будет
   */
 
  String expressionField(JRDesignParameter param, ExtraField val){
    String      exp;
    switch (val.alignmentType){
      case left:
      case center:
      case right:
      case compact:
      default:
        exp = expressionFieldName(val, true) + expressionParamNullCheck(param, val)
             + expressionFieldSufix(val);
        break;
      case dataInOneColoumnByLeft:
      case dataInOneColoumnByRight:
      case dataInOneColoumnByRightAndRigthAlign:
      case dataInOneColoumnByRightAndHalfRigthAlign:
        exp = expressionParamNullCheck(param, val) + expressionFieldSufix(val);
        break;
    }
    return exp;
  }
 
  /**
   * Создает параметр отчета, с именем ключа Map.Entry, если ключь null тогда
   * она возвращает Null, если параметр с таким именем уже был создан возврящает его.
   * @param entry - рараметр отчета
   * @return - возвращает созданый и уже добавленный в отчет парметр.
   * @throws net.sf.jasperreports.engine.JRException- по идее не когда
   */
 
  JRDesignParameter createFieldParam(Map.Entry<String, Object> entry) throws JRException{
    if (entry.getKey() == null) {
      return null;
    }
    JRDesignParameter    param = (JRDesignParameter) targetDesting.getParametersMap().get(entry.getKey());
    if (param == null){
      param = new JRDesignParameter();
      param.setValueClass(String.class);
      param.setName(entry.getKey());
      targetDesting.addParameter(param);
    }
    return param;
  }
 
  /**
   * Создает выражение для поля, по параметру отчета.
   * Автоматически меняет выражеие в зависимости от типа поля.
   * @param entry - параметр очета
   * @return - выражение используещее этот параметр, или статичное выражение,
   *      если ключ был равен null
   * @throws net.sf.jasperreports.engine.JRException - по идее не когда
   */
 
  JRDesignExpression createFieldExpression(Map.Entry<String, Object> entry) throws JRException{
    JRDesignParameter    param = createFieldParam(entry);
    String          exp;
    Object          val = entry.getValue();
    if (val != null && val instanceof ExtraField){
      ExtraField    data = (ExtraField) val;
      exp = expressionField(param, data);
     
    }
    else {
      exp = expressionParamNullCheck(param, val);
    }
    return createExpression(exp);
  }
 
  /**
   * Создает набор полей по массиву праметров отчета, где все элементы имеют простое выравниание.
   * @param startPosition - позиция начиная с которой будут созданны элементы
   * @param band - бэнд в котором будут создоватся поля
   * @param efields - массив параметров отчета, где заначения должны быть типа ExtraField
   * @return - вертикальная позиция после самой нижней точки среди всех созданных элементов
   * @throws net.sf.jasperreports.engine.JRException
   */
 
  double createFieldPackSamle(double startPosition, JRDesignBand band, ArrayList<Map.Entry<String, Object>> efields) throws JRException{
    for (Map.Entry<String, Object> entry : efields) {
      JRDesignExpression      exp = createFieldExpression(entry);
      JRDesignTextField field = createItem(FieldTypes.firstPrage, 0, (int)Math.round(startPosition),
              destingWidth, (int)Math.round(getFieldHeigth()), exp);
      switch (((ExtraField)entry.getValue()).alignmentType){
        case left:
          field.setHorizontalAlignment(JRDesignTextField.HORIZONTAL_ALIGN_LEFT);
          break;
        case center:
          field.setHorizontalAlignment(JRDesignTextField.HORIZONTAL_ALIGN_CENTER);
          break;
        case right:
          field.setHorizontalAlignment(JRDesignTextField.HORIZONTAL_ALIGN_RIGHT);
          break;
      }
      band.addElement(field);
      startPosition += field.getHeight();
    }
    return startPosition;
  }
 
  /**
   * Создает набор полей по массиву праметров отчета,
   * все элементы должны быть с независимым выравниванием данных и имени поля.
   * Функция находит размер самого большого имени поля, или самого большого значения
   * и меняет расположение имен и занчений таким образом, чтобы они оказались выравнены по одному краю.
   * @param startPosition - позиция начиная с которой будут созданны элементы
   * @param band - бэнд в котором будут создоватся поля
   * @param efields - массив параметров отчета, где заначение должно бьыть типа ExtraField
   * @return - вертикальная позиция после самой нижней точки среди всех созданных элементов
   * @throws net.sf.jasperreports.engine.JRException
   */
  double createFieldPackAligned(double startPosition, JRDesignBand band, ArrayList<Map.Entry<String, Object>> efields) throws JRException{
    double        nameSize = 0;
    double        valSize = 0;
    AlignmentType    atype = null;
   
    for (Map.Entry<String, Object> entry : efields) {
      ExtraField      val = (ExtraField) entry.getValue();
      nameSize = Math.max(nameSize, getFieldLenght(val.getNNFieldName()));
      valSize = Math.max(valSize, getFieldLenght(val.getNNFieldData() + val.getNNFieldSufix()));
      atype = val.alignmentType;
    }
   
    if (nameSize + valSize > destingWidth){
      if (nameSize > (double)destingWidth / 3d){
        //nameSize = (double)destingWidth / 3d;
        valSize = ((double)destingWidth * 2) / 3d;
        nameSize = (double)destingWidth - valSize;
      }
      else{
        valSize = (double)destingWidth - nameSize;
      }
    }
   
    double    leftPos = 0;
    switch (atype){
      case dataInOneColoumnByRight:
      case dataInOneColoumnByRightAndRigthAlign:
      case dataInOneColoumnByRightAndHalfRigthAlign:
        leftPos = (double)destingWidth - nameSize - valSize;
        break;
      case dataInOneColoumnByLeft:
        valSize = (double) destingWidth - nameSize;
        break;
    }
    for (Map.Entry<String, Object> entry : efields){
      ExtraField          val = (ExtraField) entry.getValue();
      JRDesignExpression      nameExp = createExpression(expressionFieldName(val, false));
      JRDesignExpression      dataExp = createFieldExpression(entry);
      JRDesignTextField      nameField = createItem(FieldTypes.firstPrage,
            (int)Math.round(leftPos), 0,
            (int)Math.round(nameSize), (int)Math.round(getFieldHeigth()), nameExp);
      JRDesignTextField      dataField = createItem(FieldTypes.firstPrage,
            (int)Math.round(leftPos + nameSize), 0,
            (int)Math.round(valSize), (int)Math.round(getFieldHeigth()), dataExp);
     
      nameField.setStretchType(JRDesignTextField.STRETCH_TYPE_RELATIVE_TO_BAND_HEIGHT);
      dataField.setStretchType(JRDesignTextField.STRETCH_TYPE_RELATIVE_TO_BAND_HEIGHT);
      JRDesignFrame    farme = new JRDesignFrame();
      farme.setX(0);
      farme.setY((int)Math.round(startPosition));
      farme.setWidth(destingWidth);
      farme.getLineBox().setPadding(0);
      farme.setHeight((int)Math.round(getFieldHeigth()));
      farme.setStyle(normalStyle);
      farme.setPositionType(JRDesignFrame.POSITION_TYPE_FLOAT);
      farme.addElement(nameField);
      farme.addElement(dataField);
     
      switch (val.alignmentType){
        case dataInOneColoumnByRightAndHalfRigthAlign:
          nameField.setHorizontalAlignment(JRDesignTextField.HORIZONTAL_ALIGN_RIGHT);
          break;
        case dataInOneColoumnByRightAndRigthAlign:
          nameField.setHorizontalAlignment(JRDesignTextField.HORIZONTAL_ALIGN_RIGHT);
          dataField.setHorizontalAlignment(JRDesignTextField.HORIZONTAL_ALIGN_RIGHT);
          break;       
      }
      band.addElement(farme);
      startPosition += dataField.getHeight();
    }
   
    return startPosition;
  }
 
  /**
   * Создает поле в котором собраны все данные, всех преданных в массиве efields параметров
   * @param startPosition - позиция начиная с которой будут созданны элементы
   * @param band - бэнд в котором будут создоватся поля
   * @param efields - массив параметров отчета, где заначение должно бьыть типа ExtraField
   * @return - вертикальная позиция после самой нижней точки среди всех созданных элементов
   * @throws net.sf.jasperreports.engine.JRException
   */
 
  double createFieldPackCompact(double startPosition, JRDesignBand band, ArrayList<Map.Entry<String, Object>> efields) throws JRException{
    String      exp = "";
    boolean      fistPass = true;
    for (Map.Entry<String, Object> entry : efields) {
      ExtraField          val = (ExtraField) entry.getValue();
      if (!fistPass) {
        exp += " + \" \" + ";
      }
      else {
        fistPass = false;
      }
      JRDesignParameter    param = createFieldParam(entry);
      exp += expressionField(param, val);
    }
    JRDesignExpression    dexp = createExpression(exp);
    JRDesignTextField    field = createItem(FieldTypes.firstPrage, 0,
                  (int)Math.round(startPosition), destingWidth,
                  (int)Math.round(getFieldHeigth()), dexp);
    band.addElement(field);
    startPosition += field.getHeight();
    return startPosition;
  }
 
  /**
   * Функция создает создает набор полей по параметром отчета,
   * их обекты должны быть типа ExtraField, и
   * все параметры должны иметь одинаковый тип выравнивания.
   * (в принцепе в зависимости от выравнивания поля отправляет на соодтведствующие подфункции)
   * @param startPosition - позиция начиная с которой будут созданны элементы
   * @param band - бэнд в котором будут создоватся поля
   * @param efields - массив параметров отчета, где заначение должно бьыть типа ExtraField
   * @return - вертикальная позиция после самой нижней точки среди всех созданных элементов
   * @throws net.sf.jasperreports.engine.JRException
   */

  double createFieldPack(double startPosition, JRDesignBand band, ArrayList<Map.Entry<String, Object>> efields) throws JRException{
    if (efields.size() <= 0) {
      return startPosition;
    }
    ExtraField        val = (ExtraField) efields.get(0).getValue();
    switch (val.alignmentType){
      case left:
      case center:
      case right:
        return createFieldPackSamle(startPosition, band, efields);
      case dataInOneColoumnByLeft:
      case dataInOneColoumnByRight:
      case dataInOneColoumnByRightAndRigthAlign:
      case dataInOneColoumnByRightAndHalfRigthAlign:
        return createFieldPackAligned(startPosition, band, efields);
      case compact:
        return createFieldPackSamle(startPosition, band, efields);
      default:
        throw new RuntimeException("Неизвестный тип выравнивания.");
    }
  }
 
  /**
   * Создает приметивное поле содержащие переданный параметр с выравниванивание по левому краю
   * @param startPosition - позиция начиная с которой будут отрисованны элементы
   * @param band - бэнд в котором будут создоватся поля
   * @param data - параметр отчета, на который будет ссылатся поле,
   *          если ключ null то будет созданно поле со статическими даныыми,
   *          если заначение null то будет созданно пустое поле высотой в одну строку
   * @return - вертикальная позиция после самой нижней точки среди всех созданных элементов
   * @throws net.sf.jasperreports.engine.JRException
   */
 
  double createSampleField(double startPosition, JRDesignBand band, Map.Entry<String, Object> data) throws JRException{
    JRDesignExpression    dexp = createFieldExpression(data);
    JRDesignTextField    field = createItem(FieldTypes.firstPrage, 0,
                  (int)Math.round(startPosition), destingWidth,
                  (int)Math.round(getFieldHeigth()), dexp);
    band.addElement(field);
    startPosition += field.getHeight()
    return startPosition;
  }
 
  /**
   * Заполняет банд параметрами отчета
   *
   * Разделяет массив fields на подмассивы соотведстви с форматом выравнивания
   * поля скармливает подмассивы  функции createFieldPack если они имеют тип ExtraField,
   * или функции createSampleField если это не ExtraField
   *
   * @param startPosition - позиция начиная с которой будут отрисованны элементы
   * @param band - бэнд в котором будут создоватся поля
   * @param fields - массив параметров отчета, где заначение должно бьыть типа ExtraField
   * @return
   * @throws net.sf.jasperreports.engine.JRException
   */
 
  double createReportFields(double startPosition, JRDesignBand band, Collection<Map.Entry<String, Object>> fields) throws JRException{
    double                  posistion = startPosition;
    ExtraField                startField = null;
    ArrayList<Map.Entry<String, Object>>  efields = new ArrayList<Map.Entry<String, Object>>();
    for (Iterator<Map.Entry<String, Object>> it = fields.iterator(); it.hasNext();) {
      Map.Entry<String, Object> entry = it.next();
      Object          val = entry.getValue();
      if (val != null && val instanceof ExtraField){
        if (startField != null && startField.formatEqual((ExtraField) val)){
          efields.add(entry);
        }
        else{
          if (efields.size() > 0) {
            posistion = createFieldPack(posistion, band, efields);
          }
          startField = (ExtraField) val;
          efields.clear();
          efields.add(entry);
        }
      }
      else{
        if (efields.size() > 0) {
          posistion = createFieldPack(posistion, band, efields);
        }
        startField = null;
        efields.clear();
        posistion = createSampleField(posistion, band, entry);
      }
    }
    if (efields.size() > 0) {
      posistion = createFieldPack(posistion, band, efields);
    }
    return posistion;
  }
 
  /**
   * Создает элемент заголовка отчета
   * @param startPosition - верхняя точка заголовка
   * @param band бэнд в котором будет создан заголовок
   * @param text - текст заголовка
   * @return незанятую линию сразу после заголовка
   */
  double createTitle(double startPosition, JRDesignBand band, String text){
    JRDesignExpression    dexp = createStringExpression(text);
    JRDesignTextField    field = createItem(FieldTypes.header, 0,
                  (int)Math.round(startPosition), destingWidth,
                  getHeaderHeight(), dexp);
    band.addElement(field);
    startPosition += field.getHeight()
    return startPosition;
  }
}
TOP

Related Classes of cli_fmw.report.implemenatation.JasperReportBuilder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.