xdev.tableexport.export.ReportBuilder Maven / Gradle / Ivy
package xdev.tableexport.export;
/*-
* #%L
* XDEV BI Suite
* %%
* Copyright (C) 2011 - 2020 XDEV Software
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser 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 Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* .
* #L%
*/
import java.awt.Color;
import java.awt.Font;
import java.util.HashSet;
import java.util.Set;
import javax.swing.JLabel;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRLineBox;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.design.JRDesignBand;
import net.sf.jasperreports.engine.design.JRDesignExpression;
import net.sf.jasperreports.engine.design.JRDesignField;
import net.sf.jasperreports.engine.design.JRDesignSection;
import net.sf.jasperreports.engine.design.JRDesignStaticText;
import net.sf.jasperreports.engine.design.JRDesignTextElement;
import net.sf.jasperreports.engine.design.JRDesignTextField;
import net.sf.jasperreports.engine.design.JasperDesign;
import net.sf.jasperreports.engine.type.ModeEnum;
import net.sf.jasperreports.engine.type.PositionTypeEnum;
import net.sf.jasperreports.engine.type.SplitTypeEnum;
import xdev.tableexport.config.ColumnBorder;
import xdev.tableexport.config.ColumnPadding;
import xdev.tableexport.config.ColumnStyle;
import xdev.tableexport.config.ContentColumn;
import xdev.tableexport.config.HeaderColumn;
import xdev.tableexport.config.PageProperties;
import xdev.tableexport.config.TemplateColumn;
import xdev.tableexport.config.TemplateConfig;
import xdev.vt.XdevBlob;
import xdev.vt.XdevClob;
/**
* The {@link ReportBuilder} generates a {@link JasperReport} based on the
* information of the {@link TemplateConfig}.
*
* @author XDEV Software (FHAE)
*
* @see TemplateConfig
* @see ReportExporter
*
*/
public class ReportBuilder
{
private TemplateConfig config;
private Set fieldSet = new HashSet<>();
public ReportBuilder(TemplateConfig tempConfig)
{
this.config = tempConfig;
}
private JRDesignBand initDetailBand()
{
final JRDesignBand detailBand = new JRDesignBand();
detailBand.setHeight(TemplateConfig.DEFAULT_DETAIL_BAND_HEIGHT);
detailBand.setSplitType(SplitTypeEnum.STRETCH);
return detailBand;
}
private JRDesignBand initHeaderBand()
{
// Header
final JRDesignBand headerBand = new JRDesignBand();
headerBand.setHeight(TemplateConfig.DEFAULT_HEADER_BAND_HEIGHT);
return headerBand;
}
private JasperDesign createDefaultDesign()
{
JasperDesign jasperDesign = new JasperDesign();
jasperDesign.setName("DefaultDesign");
PageProperties properties = this.config.getPageProperties();
jasperDesign.setPageWidth(calcPageWidth(properties));
jasperDesign.setColumnWidth(calcColumnsWidth());
jasperDesign.setPageHeight(properties.getPageHeight());
jasperDesign.setColumnSpacing(properties.getColumnSpacing());
jasperDesign.setLeftMargin(properties.getLeftMargin());
jasperDesign.setRightMargin(properties.getRightMargin());
jasperDesign.setTopMargin(properties.getTopMargin());
jasperDesign.setBottomMargin(properties.getBottomMargin());
return jasperDesign;
}
private int calcColumnsWidth()
{
int width = 0;
for(TemplateColumn col : this.config.getColumns())
{
width += col.getWidth();
}
return width;
}
/***
* Calculated the page width including the margins.
*
* @param properties
*
* @return
*/
private int calcPageWidth(final PageProperties properties)
{
int width = 0;
for(TemplateColumn col : this.config.getColumns())
{
width += col.getWidth();
}
width += properties.getLeftMargin() + properties.getRightMargin();
return width;
}
/**
*
* @return
*/
private int calcMaxHeaderHeight()
{
final JLabel lbl = new JLabel("a");
int maxHeight = 0;
for(TemplateColumn col : this.config.getColumns())
{
final ColumnStyle style = col.getHeaderColumn().getStyle();
final Font font = style.getFont();
lbl.setFont(font);
//get the normal height of the label
int lblHeigh = (int)lbl.getPreferredSize().getHeight();
//add the column border width
lblHeigh+= style.getColBorder().getLineWidth()*2;
//Add padding
lblHeigh+= style.getColumnPadding().getTopWidth() + style.getColumnPadding().getBottomWidth();
if(lblHeigh > maxHeight) maxHeight = lblHeigh;
}
return maxHeight;
}
private int calcMaxContentHeight()
{
final JLabel lbl = new JLabel("a");
int maxHeight = 0;
for(TemplateColumn col : this.config.getColumns())
{
final ColumnStyle style = col.getContentColumn().getStyle();
final Font font = style.getFont();
lbl.setFont(font);
int lblHeigh = (int)lbl.getPreferredSize().getHeight();
//Add border width
lblHeigh+= style.getColBorder().getLineWidth()*2;
//Add padding
lblHeigh+= style.getColumnPadding().getTopWidth() + style.getColumnPadding().getBottomWidth();
if(lblHeigh > maxHeight) maxHeight = lblHeigh;
}
return maxHeight;
}
private void createTemplateFields(final JasperDesign jasperDesign) throws ExportException
{
JRDesignField field;
for(TemplateColumn col : this.config.getColumns())
{
field = new JRDesignField();
field.setName(col.getContentColumn().getFieldName());
chooseValueClass(col,field);
try
{
jasperDesign.addField(field);
this.fieldSet.add(field);
}
catch(JRException e)
{
throw new ExportException("error during add the field "
+ col.getContentColumn().getFieldName(),e);
}
}
}
private JRDesignField chooseValueClass(final TemplateColumn col, final JRDesignField field)
{
final Class> valueClass = col.getContentColumn().getColumnValueClass();
if(valueClass.isAssignableFrom(byte[].class) || valueClass.isAssignableFrom(XdevBlob.class) || valueClass.isAssignableFrom(XdevClob.class))
{
field.setValueClass(String.class);
}
else
{
field.setValueClass(valueClass);
}
return field;
}
private void createHeaderAndContent(JRDesignBand headerBand, JRDesignBand detailBand)
{
JRDesignStaticText headerLabel;
JRDesignStaticText emptyHeaderLabel;
JRDesignTextField textField;
final int headerLabelHeight = calcMaxHeaderHeight();
headerBand.setHeight(headerLabelHeight);
final int contentLabelHeight = calcMaxContentHeight();
detailBand.setHeight(contentLabelHeight);
final boolean createHeader = this.config.hasAnyHeader();
int x = 0;
for(TemplateColumn col : this.config.getColumns())
{
// Header is created
if(createHeader)
{
// If this column has a header the JRDesignStaticText get the
// propertys of the Column
if(col.hasHeaderColumn())
{
HeaderColumn headerColumn = col.getHeaderColumn();
// Build label and set x / y
headerLabel = new JRDesignStaticText();
headerLabel.setX(x);
headerLabel.setWidth(col.getWidth());
headerLabel.setY(TemplateConfig.DEFAULT_COMPONENT_Y_POSITION);
headerLabel.setHeight(headerLabelHeight);
setStlyeForTextField(headerLabel,headerColumn.getStyle());
prepareTextfieldWithBorder(headerLabel,headerColumn.getStyle());
prepareTextfieldPadding(headerLabel,headerColumn.getStyle());
headerLabel.setPositionType(PositionTypeEnum.FLOAT);
// Get the Property
headerLabel.setText(headerColumn.getProperty());
headerBand.addElement(headerLabel);
}
else
{
// an empty label must be added to complete the layout
// Build label and set x / y
emptyHeaderLabel = new JRDesignStaticText();
emptyHeaderLabel.setX(x);
emptyHeaderLabel.setWidth(col.getWidth());
headerBand.addElement(emptyHeaderLabel);
}
}
final ContentColumn contentColumn = col.getContentColumn();
textField = new JRDesignTextField();
textField.setX(x);
textField.setWidth(col.getWidth());
textField.setY(TemplateConfig.DEFAULT_COMPONENT_Y_POSITION);
textField.setHeight(contentLabelHeight);
setStlyeForTextField(textField,contentColumn.getStyle());
textField.setPattern(contentColumn.getProperty());
// box tag properties
prepareTextfieldWithBorder(textField,contentColumn.getStyle());
prepareTextfieldPadding(textField,contentColumn.getStyle());
textField.setExpression(buildExpression(contentColumn));
textField.setPositionType(PositionTypeEnum.FLOAT);
if(config.isBlankWhenNullValue())
textField.setBlankWhenNull(true);
detailBand.addElement(textField);
x += col.getWidth();
}
}
private void setStlyeForTextField(final JRDesignTextElement txtField, final ColumnStyle style)
{
txtField.setBackcolor(style.getBackground());
txtField.setForecolor(style.getForeground());
// Font
final Font f = style.getFont();
txtField.setFontName(f.getName());
txtField.setFontSize(f.getSize());
txtField.setBold(f.isBold());
txtField.setItalic(f.isItalic());
txtField.setHorizontalAlignment(style.getHorizontalAlignment().getHorizontalAlignEnum());
if(!style.getBackground().equals(Color.WHITE))
{
txtField.setMode(ModeEnum.OPAQUE);
}
}
private void prepareTextfieldWithBorder(final JRDesignTextElement textField, final ColumnStyle style)
{
final ColumnBorder border = style.getColBorder();
if(border == null)
return;
textField.getLineBox().getPen().setLineWidth(border.getLineWidth());
textField.getLineBox().getPen().setLineColor(border.getLineColor());
textField.getLineBox().getPen().setLineStyle(border.getLineStyle().getLineStyleEnum());
}
private void prepareTextfieldPadding(final JRDesignTextElement textField, final ColumnStyle style)
{
final ColumnPadding colPadding = style.getColumnPadding();
final JRLineBox lineBox = textField.getLineBox();
lineBox.setTopPadding(colPadding.getTopWidth());
lineBox.setRightPadding(colPadding.getRightWidth());
lineBox.setLeftPadding(colPadding.getLeftWidth());
lineBox.setBottomPadding(colPadding.getBottomWidth());
}
private JRDesignExpression buildExpression(ContentColumn column)
{
JRDesignExpression expression = new JRDesignExpression();
expression.setText("$F{" + column.getFieldName() + "}");
return expression;
}
/**
*
* Assemble and compile a {@link JasperReport} based on the information of
* the {@link TemplateConfig} object.
*
* @return the compiled {@link JasperReport}
* @throws ExportException
*/
public JasperReport assembleReport() throws ExportException
{
try
{
final JasperDesign jasperDesign = createDefaultDesign();
createTemplateFields(jasperDesign);
final JRDesignBand headerBand = initHeaderBand();
final JRDesignBand detailBand = initDetailBand();
createHeaderAndContent(headerBand,detailBand);
((JRDesignSection)jasperDesign.getDetailSection()).addBand(detailBand);
if(this.config.hasAnyHeader())
{
jasperDesign.setTitle(headerBand);
}
return JasperCompileManager.compileReport(jasperDesign);
}
catch(Exception e)
{
throw new ExportException(e);
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy