com.qcadoo.report.internal.PdfHelperImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.qcadoo.report.internal.PdfHelperImpl.java

Source

/**
 * ***************************************************************************
 * Copyright (c) 2010 Qcadoo Limited
 * Project: Qcadoo Framework
 * Version: 1.4
 *
 * This file is part of Qcadoo.
 *
 * Qcadoo 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 Affero 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, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 * ***************************************************************************
 */
package com.qcadoo.report.internal;

import com.google.common.collect.Lists;
import com.lowagie.text.*;
import com.lowagie.text.pdf.PdfPCell;
import com.lowagie.text.pdf.PdfPTable;
import com.lowagie.text.pdf.draw.LineSeparator;
import com.qcadoo.localization.api.TranslationService;
import com.qcadoo.localization.api.utils.DateUtils;
import com.qcadoo.model.api.DataDefinitionService;
import com.qcadoo.model.api.Entity;
import com.qcadoo.report.api.ColorUtils;
import com.qcadoo.report.api.FontUtils;
import com.qcadoo.report.api.pdf.HeaderAlignment;
import com.qcadoo.report.api.pdf.PdfHelper;
import com.qcadoo.report.api.pdf.TableBorderEvent;
import com.qcadoo.security.api.SecurityService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.net.MalformedURLException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;

import static org.springframework.context.i18n.LocaleContextHolder.getLocale;

@Component
public final class PdfHelperImpl implements PdfHelper {

    private static final Logger LOG = LoggerFactory.getLogger(PdfHelperImpl.class);

    private static final Integer MINIMUM_ALLOWABLE_SIZE_COLUMN_IN_PIXEL = 63;

    private static final String QCADOO_SECURITY = "qcadooSecurity";

    private static final String USER = "user";

    private static final String FIRST_NAME = "firstName";

    private static final String LAST_NAME = "lastName";

    private static final String USER_NAME = "userName";

    @Autowired
    private DataDefinitionService dataDefinitionService;

    @Autowired
    private TranslationService translationService;

    @Autowired
    private SecurityService securityService;

    @Override
    public void addDocumentHeader(final Document document, final String name, final String documenTitle,
            final String documentAuthor, final Date date, final String username) throws DocumentException {
        SimpleDateFormat df = new SimpleDateFormat(DateUtils.L_DATE_TIME_FORMAT, getLocale());
        LineSeparator line = new LineSeparator(3, 100f, ColorUtils.getLineDarkColor(), Element.ALIGN_LEFT, 0);
        document.add(Chunk.NEWLINE);
        Paragraph title = new Paragraph(new Phrase(documenTitle, FontUtils.getDejavuBold17Light()));
        title.add(new Phrase(" " + name, FontUtils.getDejavuBold17Dark()));
        title.setSpacingAfter(7f);
        document.add(title);
        document.add(line);
        PdfPTable userAndDate = new PdfPTable(2);
        userAndDate.setWidthPercentage(100f);
        userAndDate.setHorizontalAlignment(Element.ALIGN_LEFT);
        userAndDate.getDefaultCell().setBorderWidth(0);
        Paragraph userParagraph = new Paragraph(new Phrase(documentAuthor, FontUtils.getDejavuRegular9Light()));
        userParagraph.add(new Phrase(" " + username, FontUtils.getDejavuRegular9Dark()));
        Paragraph dateParagraph = new Paragraph(df.format(date), FontUtils.getDejavuRegular9Light());
        userAndDate.addCell(userParagraph);
        userAndDate.getDefaultCell().setHorizontalAlignment(Element.ALIGN_RIGHT);
        userAndDate.addCell(dateParagraph);
        userAndDate.setSpacingAfter(14f);
        document.add(userAndDate);
    }

    @Override
    public void addDocumentHeader(final Document document, final String name, final String documenTitle,
            final String documentAuthor, final Date date) throws DocumentException {
        SimpleDateFormat df = new SimpleDateFormat(DateUtils.L_DATE_TIME_FORMAT, getLocale());
        LineSeparator line = new LineSeparator(2, 100f, ColorUtils.getLineDarkColor(), Element.ALIGN_LEFT, 0);
        document.add(Chunk.NEWLINE);
        Paragraph title = new Paragraph(new Phrase(documenTitle, FontUtils.getDejavuBold17Light()));
        title.add(new Phrase(" " + name, FontUtils.getDejavuBold17Dark()));
        title.setSpacingAfter(7f);
        document.add(title);
        document.add(line);
        PdfPTable userAndDate = new PdfPTable(2);
        userAndDate.setWidthPercentage(100f);
        userAndDate.setHorizontalAlignment(Element.ALIGN_LEFT);
        userAndDate.getDefaultCell().setBorderWidth(0);
        Paragraph userParagraph = new Paragraph(new Phrase(documentAuthor, FontUtils.getDejavuRegular9Light()));
        userParagraph.add(new Phrase(" " + getDocumentAuthor(), FontUtils.getDejavuRegular9Dark()));
        Paragraph dateParagraph = new Paragraph(df.format(date), FontUtils.getDejavuRegular9Light());
        userAndDate.addCell(userParagraph);
        userAndDate.getDefaultCell().setHorizontalAlignment(Element.ALIGN_RIGHT);
        userAndDate.addCell(dateParagraph);
        userAndDate.setSpacingAfter(14f);
        document.add(userAndDate);
    }

    @Override
    public void addDocumentHeaderThin(final Document document, final String name, final String documentTitle,
            final String documentAuthor, final Date date) throws DocumentException {
        SimpleDateFormat df = new SimpleDateFormat(DateUtils.L_DATE_TIME_FORMAT, getLocale());
        LineSeparator line = new LineSeparator(2, 100f, ColorUtils.getLineDarkColor(), Element.ALIGN_LEFT, 0);
        Paragraph title = new Paragraph(new Phrase(documentTitle, FontUtils.getDejavuBold14Light()));
        title.add(new Phrase(" " + name, FontUtils.getDejavuBold14Dark()));
        title.setSpacingAfter(7f);
        document.add(title);
        document.add(line);
        PdfPTable userAndDate = new PdfPTable(2);
        userAndDate.setWidthPercentage(100f);
        userAndDate.setHorizontalAlignment(Element.ALIGN_LEFT);
        userAndDate.getDefaultCell().setBorderWidth(0);
        Paragraph userParagraph = new Paragraph(new Phrase(documentAuthor, FontUtils.getDejavuRegular9Light()));
        userParagraph.add(new Phrase(" " + getDocumentAuthor(), FontUtils.getDejavuRegular9Dark()));
        Paragraph dateParagraph = new Paragraph(df.format(date), FontUtils.getDejavuRegular9Light());
        userAndDate.addCell(userParagraph);
        userAndDate.getDefaultCell().setHorizontalAlignment(Element.ALIGN_RIGHT);
        userAndDate.addCell(dateParagraph);
        userAndDate.setSpacingAfter(10f);
        document.add(userAndDate);
    }

    @Override
    public void addMetaData(final Document document) {
        document.addSubject("Using iText");
        document.addKeywords("Java, PDF, iText");
        document.addAuthor("QCADOO");
        document.addCreator("QCADOO");
    }

    @Override
    public PdfPTable createPanelTable(final int column) {
        PdfPTable mainData = new PdfPTable(column);
        mainData.setWidthPercentage(100f);
        mainData.getDefaultCell().setBorder(Rectangle.NO_BORDER);
        mainData.getDefaultCell().setVerticalAlignment(Element.ALIGN_TOP);
        mainData.getDefaultCell().setPadding(4.0f);
        mainData.setTableEvent(new TableBorderEvent());
        return mainData;
    }

    @Override
    public PdfPTable createPanelTableWithSimpleFormat(final int column) {
        PdfPTable pdfPTable = new PdfPTable(column);
        pdfPTable.getDefaultCell().setBorder(Rectangle.NO_BORDER);
        pdfPTable.getDefaultCell().setPadding(6.0f);
        pdfPTable.getDefaultCell().setVerticalAlignment(PdfPCell.ALIGN_TOP);
        return pdfPTable;
    }

    @Override
    public void addTableCellAsTable(final PdfPTable table, final String label, final Object fieldValue,
            final Font headerFont, final Font valueFont, final int columns) {
        addTableCellAsTable(table, label, fieldValue, "-", headerFont, valueFont, columns);
    }

    @Override
    public void addTableCellAsTable(final PdfPTable table, final String label, final Object fieldValue,
            final String nullValue, final Font headerFont, final Font valueFont, final int columns) {
        addTableCellAsTable(table, label, fieldValue, nullValue, headerFont, valueFont, columns, new int[] {});
    }

    private void addTableCellAsTable(final PdfPTable table, final String label, final Object fieldValue,
            final String nullValue, final Font headerFont, final Font valueFont, final int columns,
            final int[] columnWidths) {
        PdfPTable cellTable = new PdfPTable(columns);

        if (columnWidths.length > 0) {
            try {
                cellTable.setWidths(columnWidths);
            } catch (DocumentException e) {
                LOG.error(e.getMessage(), e);
            }
        }

        cellTable.getDefaultCell().setBorder(Rectangle.NO_BORDER);
        cellTable.addCell(new Phrase(label, headerFont));

        if (fieldValue == null) {
            cellTable.addCell(new Phrase(nullValue, valueFont));
        } else {
            cellTable.addCell(new Phrase(fieldValue.toString(), valueFont));
        }

        table.addCell(cellTable);
    }

    @Override
    public void addTableCellAsTwoColumnsTable(final PdfPTable table, final String label, final Object fieldValue) {
        addTableCellAsTable(table, label, fieldValue, FontUtils.getDejavuBold7Dark(),
                FontUtils.getDejavuRegular9Dark(), 2);
    }

    @Override
    public void addTableCellAsTwoColumnsTable(final PdfPTable table, final String label, final Object fieldValue,
            final int[] columnWidths) {
        addTableCellAsTable(table, label, fieldValue, "-", FontUtils.getDejavuBold7Dark(),
                FontUtils.getDejavuRegular9Dark(), 2, columnWidths);
    }

    @Override
    public void addTableCellAsOneColumnTable(final PdfPTable table, final String label, final Object fieldValue) {
        addTableCellAsTable(table, label, fieldValue, FontUtils.getDejavuBold7Dark(),
                FontUtils.getDejavuRegular9Dark(), 1);
    }

    @Override
    public void addImage(final Document document, final String fileName) {
        try {
            Image img = Image.getInstance(fileName);
            if (img.getWidth() > 515 || img.getHeight() > 370) {
                img.scaleToFit(515, 370);
            }

            document.add(img);
            document.add(Chunk.NEWLINE);
        } catch (BadElementException e) {
            LOG.error(e.getMessage(), e);
        } catch (MalformedURLException e) {
            LOG.error(e.getMessage(), e);
        } catch (IOException e) {
            LOG.error(e.getMessage(), e);
        } catch (DocumentException e) {
            LOG.error(e.getMessage(), e);
        }
    }

    @Override
    public PdfPTable createTableWithHeader(int numOfColumns, List<String> header, boolean lastColumnAlignmentToLeft,
            HeaderAlignment headerAlignment) {
        PdfPTable table = new PdfPTable(numOfColumns);
        return setTableProperties(header, lastColumnAlignmentToLeft, table, null);
    }

    @Override
    public PdfPTable createTableWithHeader(final int numOfColumns, final List<String> header,
            final boolean lastColumnAlignmentToLeft, final int[] columnWidths,
            final Map<String, HeaderAlignment> alignments) {
        PdfPTable table = new PdfPTable(numOfColumns);
        try {
            table.setWidths(columnWidths);
        } catch (DocumentException e) {
            LOG.error(e.getMessage(), e);
        }
        return setTableProperties(header, lastColumnAlignmentToLeft, table, alignments);
    }

    @Override
    public PdfPTable createTableWithHeader(final int numOfColumns, final List<String> header,
            final boolean lastColumnAlignmentToLeft, final int[] columnWidths, final HeaderAlignment alignment) {
        PdfPTable table = new PdfPTable(numOfColumns);
        try {
            table.setWidths(columnWidths);
        } catch (DocumentException e) {
            LOG.error(e.getMessage(), e);
        }
        return setTableProperties(header, lastColumnAlignmentToLeft, table, null);
    }

    @Override
    public PdfPTable createTableWithHeader(final int numOfColumns, final List<String> header,
            final boolean lastColumnAlignmentToLeft, final Map<String, HeaderAlignment> alignments) {
        PdfPTable table = new PdfPTable(numOfColumns);
        return setTableProperties(header, lastColumnAlignmentToLeft, table, alignments);
    }

    @Override
    public PdfPTable createTableWithHeader(final int numOfColumns, final List<String> header,
            final boolean lastColumnAlignmentToLeft, final int[] columnWidths) {
        PdfPTable table = new PdfPTable(numOfColumns);
        try {
            table.setWidths(columnWidths);
        } catch (DocumentException e) {
            LOG.error(e.getMessage(), e);
        }
        return setTableProperties(header, lastColumnAlignmentToLeft, table, null);
    }

    @Override
    public PdfPTable createTableWithHeader(final int numOfColumns, final List<String> header,
            final boolean lastColumnAlignmentToLeft) {
        PdfPTable table = new PdfPTable(numOfColumns);
        return setTableProperties(header, lastColumnAlignmentToLeft, table, null);
    }

    @Override
    public int getMaxSizeOfColumnsRows(final List<Integer> columnsListSize) {
        int size = 0;
        for (int columnSize : columnsListSize) {
            if (columnSize > size) {
                size = columnSize;
            }
        }
        return size;
    }

    @Override
    public PdfPTable addDynamicHeaderTableCell(final PdfPTable headerTable, final Map<String, Object> column,
            final Locale locale) {
        if (column.keySet().size() != 0) {
            Object key = column.keySet().iterator().next();
            addTableCellAsOneColumnTable(headerTable, translationService.translate(key.toString(), locale),
                    column.get(key));
            column.remove(key);
        }
        return headerTable;
    }

    @Override
    public PdfPTable addDynamicHeaderTableCellOneRow(final PdfPTable headerTable, final Map<String, Object> column,
            final Locale locale) {
        if (column.keySet().size() != 0) {
            Object key = column.keySet().iterator().next();
            addTableCellAsTwoColumnsTable(headerTable, translationService.translate(key.toString(), locale),
                    column.get(key));
            column.remove(key);
        }
        return headerTable;
    }

    private PdfPTable setTableProperties(final List<String> header, final boolean lastColumnAligmentToLeft,
            final PdfPTable table, final Map<String, HeaderAlignment> alignments) {
        table.setWidthPercentage(100f);
        table.setHorizontalAlignment(Element.ALIGN_LEFT);
        table.setSpacingBefore(7.0f);
        // table.getDefaultCell().setBackgroundColor(ColorUtils.getBackgroundColor());
        table.getDefaultCell().setBorderColor(ColorUtils.getLineDarkColor());
        table.getDefaultCell().setBorderWidth(1.0f);
        table.getDefaultCell().setVerticalAlignment(Element.ALIGN_MIDDLE);
        table.getDefaultCell().setPadding(5.0f);
        table.getDefaultCell().disableBorderSide(Rectangle.RIGHT);

        if (alignments == null || alignments.isEmpty()) {
            table.getDefaultCell().setHorizontalAlignment(Element.ALIGN_LEFT);
            int i = 0;
            for (String element : header) {
                i++;
                if (i == header.size()) {
                    table.getDefaultCell().enableBorderSide(Rectangle.RIGHT);
                }
                table.addCell(new Phrase(element, FontUtils.getDejavuBold7Dark()));
                if (i == 1) {
                    table.getDefaultCell().disableBorderSide(Rectangle.LEFT);
                }
            }
        } else {
            int i = 0;

            for (String element : header) {
                i++;
                HeaderAlignment alignment = alignments.get(element);
                if (HeaderAlignment.LEFT.equals(alignment)) {
                    table.getDefaultCell().setHorizontalAlignment(Element.ALIGN_LEFT);
                } else if (HeaderAlignment.RIGHT.equals(alignment)) {
                    table.getDefaultCell().setHorizontalAlignment(Element.ALIGN_RIGHT);
                }
                if (i == header.size()) {
                    table.getDefaultCell().enableBorderSide(Rectangle.RIGHT);
                }
                table.addCell(new Phrase(element, FontUtils.getDejavuBold7Dark()));
                if (i == 1) {
                    table.getDefaultCell().disableBorderSide(Rectangle.LEFT);
                }
            }
        }
        table.getDefaultCell().setHorizontalAlignment(Element.ALIGN_LEFT);
        table.getDefaultCell().setBackgroundColor(null);
        table.getDefaultCell().disableBorderSide(Rectangle.RIGHT);
        table.getDefaultCell().setBorderColor(ColorUtils.getLineLightColor());
        return table;
    }

    @Override
    public int[] getReportColumnWidths(Integer availableWidth, Map<String, Integer> fixedColumns,
            List<String> allColumns) {
        int[] reportColumnWidths = new int[allColumns.size()];
        Integer remainedAvailableWidth = availableWidth;
        Map<Integer, Integer> columnWithFixedWidth = new HashMap<Integer, Integer>();
        int i = 0;
        for (String entryColumn : allColumns) {
            for (Map.Entry<String, Integer> entryFixedColumn : fixedColumns.entrySet()) {
                if (entryColumn.toLowerCase().contains(entryFixedColumn.getKey().toLowerCase())) {
                    remainedAvailableWidth = remainedAvailableWidth - entryFixedColumn.getValue();
                    columnWithFixedWidth.put(i, entryFixedColumn.getValue());
                }
            }
            i++;
        }

        Integer columnWithoutFixedWidth = allColumns.size() - columnWithFixedWidth.size();
        if (allColumns.size() == columnWithFixedWidth.size() && remainedAvailableWidth >= 0) {
            for (Map.Entry<Integer, Integer> entry : columnWithFixedWidth.entrySet()) {
                reportColumnWidths[entry.getKey()] = entry.getValue();
            }
        } else if (remainedAvailableWidth >= 0
                && remainedAvailableWidth > columnWithoutFixedWidth * MINIMUM_ALLOWABLE_SIZE_COLUMN_IN_PIXEL) {
            Integer columnSize = remainedAvailableWidth / columnWithoutFixedWidth;
            Arrays.fill(reportColumnWidths, columnSize);
            for (Map.Entry<Integer, Integer> entry : columnWithFixedWidth.entrySet()) {
                reportColumnWidths[entry.getKey()] = entry.getValue();
            }
        } else {
            Arrays.fill(reportColumnWidths, MINIMUM_ALLOWABLE_SIZE_COLUMN_IN_PIXEL);
            for (Map.Entry<Integer, Integer> entry : columnWithFixedWidth.entrySet()) {
                reportColumnWidths[entry.getKey()] = entry.getValue();
            }
            int sumColumnWidths = getSumColumnWidths(reportColumnWidths);
            for (int k = 0; k < reportColumnWidths.length; k++) {
                reportColumnWidths[k] = getScaledColumnWidth(sumColumnWidths, reportColumnWidths[k],
                        availableWidth);
            }
        }
        return reportColumnWidths;
    }

    private int getSumColumnWidths(final int[] reportColumnWidths) {
        int sumColumnsWidth = 0;
        for (int k = 0; k < reportColumnWidths.length; k++) {
            sumColumnsWidth += reportColumnWidths[k];
        }
        return sumColumnsWidth;
    }

    private int getScaledColumnWidth(final int sumColumnWidths, final int columnWidth, int availableWidth) {
        int scaledColumnWidth = (columnWidth * 100) / sumColumnWidths;
        return (scaledColumnWidth * availableWidth) / 100;
    }

    @Override
    public String getDocumentAuthor() {
        Entity user = dataDefinitionService.get(QCADOO_SECURITY, USER).get(securityService.getCurrentUserId());
        String firstName = user.getStringField(FIRST_NAME);
        String lastName = user.getStringField(LAST_NAME);
        String userName = user.getStringField(USER_NAME);
        String documentAuthor = "";

        if (!StringUtils.isEmpty(firstName)) {
            documentAuthor += firstName;
        }
        if (!StringUtils.isEmpty(lastName)) {
            if (StringUtils.isEmpty(documentAuthor)) {
                documentAuthor += lastName;
            } else {
                documentAuthor += " " + lastName;
            }
        }
        if (StringUtils.isEmpty(documentAuthor)) {
            documentAuthor = userName;
        } else {
            documentAuthor += " (" + userName + ")";
        }

        return documentAuthor;
    }

    @Override
    public boolean validateReportColumnWidths(Integer availableWidth, Map<String, Integer> fixedColumns,
            List<String> allColumns) {
        Integer remainedAvailableWidth = availableWidth;
        for (String entryColumn : allColumns) {
            for (Map.Entry<String, Integer> entryFixedColumn : fixedColumns.entrySet()) {
                if (entryColumn.toLowerCase().contains(entryFixedColumn.getKey().toLowerCase())) {
                    remainedAvailableWidth = remainedAvailableWidth - entryFixedColumn.getValue();
                }
            }
        }
        if (remainedAvailableWidth >= 0) {
            return true;
        }
        return false;
    }
}