be.roots.taconic.pricingguide.util.iTextUtil.java Source code

Java tutorial

Introduction

Here is the source code for be.roots.taconic.pricingguide.util.iTextUtil.java

Source

package be.roots.taconic.pricingguide.util;

/**
 *  This file is part of the Taconic Pricing Guide generator.  This code will
 *  generate a full featured PDF Pricing Guide by using using iText
 *  (http://www.itextpdf.com) based on JSON files.
 *
 *  Copyright (C) 2015  Roots nv
 *  Authors: Koen Dehaen (koen.dehaen@roots.be)
 *
 *  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 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, see <http://www.gnu.org/licenses/>.
 *
 *  For more information, please contact Roots nv at this address: support@roots.be
 *
 */

import be.roots.taconic.pricingguide.domain.Toc;
import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import com.itextpdf.text.pdf.parser.PdfReaderContentParser;
import org.apache.log4j.Logger;
import org.springframework.util.CollectionUtils;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class iTextUtil {

    private final static Logger LOGGER = Logger.getLogger(iTextUtil.class);

    public static final int PAGE_MARGIN_TOP = 72;
    public static final Rectangle PAGE_SIZE = PageSize.LETTER;
    public static final int PAGE_HEIGHT = (int) PAGE_SIZE.getHeight() - (PAGE_MARGIN_TOP * 2) - 20;

    private static final Font FONT_COVER_TEXT;
    private static final Font FONT_COVER_PRICINGGUIDE;
    private static final Font FONT_COVER_YEAR;

    private static final Font FONT_PERSONALIZATION;
    private static final Font FONT_DISCLAIMER;

    private static final Font FONT_TOC_TITLE;
    private static final Font FONT_TOC;
    private static final Font FONT_TOC_BOLD;
    private static final Font FONT_TOC_SYMBOL;

    private static final Font FONT_PAGE_NUMBER;

    private static final Font FONT_MODEL_TITLE;
    private static final Font FONT_MODEL_SYMBOL;
    private static final Font FONT_MODEL_CATEGORY;
    private static final Font FONT_MODEL_KEY;
    private static final Font FONT_MODEL_VALUE;
    private static final Font FONT_MODEL_PRICING_TITLE;
    private static final Font FONT_MODEL_PRICING_DATA;
    private static final Font FONT_MODEL_PRICING_MESSAGE;
    private static final Font FONT_CONTACT_US;
    private static final Font FONT_BUTTON;

    private static final BaseColor PURPLE;
    private static final BaseColor SILVER;
    private static final BaseColor TACONIC_RED;

    static {

        PURPLE = new BaseColor(93, 32, 91);
        SILVER = new BaseColor(239, 239, 239);
        TACONIC_RED = new BaseColor(237, 32, 40);

        BaseFont lightFont = null;
        BaseFont mediumFont = null;

        try {

            lightFont = BaseFont.createFont("GothamSSm-Light.otf", BaseFont.WINANSI, BaseFont.EMBEDDED);
            lightFont.setSubset(false);
            mediumFont = BaseFont.createFont("GothamSSm-Medium.otf", BaseFont.WINANSI, BaseFont.EMBEDDED);
            lightFont.setSubset(false);

        } catch (DocumentException | IOException e) {
            LOGGER.error(e.getLocalizedMessage(), e);
        }

        FONT_COVER_TEXT = new Font(lightFont, 18, Font.NORMAL, TACONIC_RED);
        FONT_COVER_PRICINGGUIDE = new Font(lightFont, 24, Font.NORMAL, PURPLE);
        FONT_COVER_YEAR = new Font(lightFont, 38, Font.NORMAL, PURPLE);

        FONT_PERSONALIZATION = new Font(mediumFont, 12, Font.NORMAL, BaseColor.DARK_GRAY);
        FONT_DISCLAIMER = new Font(lightFont, 10, Font.NORMAL, BaseColor.DARK_GRAY);

        FONT_TOC_TITLE = new Font(lightFont, 16, Font.NORMAL, BaseColor.DARK_GRAY);
        FONT_TOC = new Font(lightFont, 10, Font.NORMAL, BaseColor.DARK_GRAY);
        FONT_TOC_BOLD = new Font(lightFont, 10, Font.BOLD, BaseColor.DARK_GRAY);
        FONT_TOC_SYMBOL = new Font(Font.FontFamily.SYMBOL, 10, Font.NORMAL, BaseColor.DARK_GRAY);

        FONT_PAGE_NUMBER = new Font(Font.FontFamily.HELVETICA, 7, Font.NORMAL, BaseColor.GRAY);

        FONT_MODEL_TITLE = new Font(mediumFont, 12, Font.BOLD, PURPLE);
        FONT_MODEL_SYMBOL = new Font(Font.FontFamily.SYMBOL, 12, Font.BOLD, PURPLE);
        FONT_MODEL_CATEGORY = new Font(mediumFont, 10, Font.BOLD, PURPLE);
        FONT_MODEL_KEY = new Font(mediumFont, 8, Font.BOLD, BaseColor.DARK_GRAY);
        FONT_MODEL_VALUE = new Font(lightFont, 8, Font.NORMAL, BaseColor.DARK_GRAY);

        FONT_MODEL_PRICING_TITLE = new Font(lightFont, 7, Font.BOLD, BaseColor.WHITE);
        FONT_MODEL_PRICING_DATA = new Font(lightFont, 7, Font.NORMAL, BaseColor.DARK_GRAY);
        FONT_MODEL_PRICING_MESSAGE = new Font(lightFont, 6, Font.NORMAL, BaseColor.DARK_GRAY);

        FONT_CONTACT_US = new Font(mediumFont, 12, Font.BOLD, PURPLE);

        FONT_BUTTON = new Font(mediumFont, 10, Font.BOLD, BaseColor.WHITE);

    }

    public static BaseColor getPurple() {
        return PURPLE;
    }

    public static BaseColor getSilver() {
        return SILVER;
    }

    public static BaseColor getTaconicRed() {
        return TACONIC_RED;
    }

    public static Font getFontCoverText() {
        return FONT_COVER_TEXT;
    }

    public static Font getFontCoverPricingguide() {
        return FONT_COVER_PRICINGGUIDE;
    }

    public static Font getFontCoverYear() {
        return FONT_COVER_YEAR;
    }

    public static Font getFontTocSymbol() {
        return FONT_TOC_SYMBOL;
    }

    public static Font getFontTocTitle() {
        return FONT_TOC_TITLE;
    }

    public static Font getFontToc() {
        return FONT_TOC;
    }

    public static Font getFontTocBold() {
        return FONT_TOC_BOLD;
    }

    public static Font getFontPersonalization() {
        return FONT_PERSONALIZATION;
    }

    public static Font getFontPageNumber() {
        return FONT_PAGE_NUMBER;
    }

    public static Font getFontModelTitle() {
        return FONT_MODEL_TITLE;
    }

    public static Font getFontModelKey() {
        return FONT_MODEL_KEY;
    }

    public static Font getFontModelValue() {
        return FONT_MODEL_VALUE;
    }

    public static Font getFontModelCategory() {
        return FONT_MODEL_CATEGORY;
    }

    public static Font getFontModelPricingTitle() {
        return FONT_MODEL_PRICING_TITLE;
    }

    public static Font getFontModelPricingData() {
        return FONT_MODEL_PRICING_DATA;
    }

    public static Font getFontModelPricingMessage() {
        return FONT_MODEL_PRICING_MESSAGE;
    }

    public static Font getFontModelSymbol() {
        return FONT_MODEL_SYMBOL;
    }

    public static Font getFontDisclaimer() {
        return FONT_DISCLAIMER;
    }

    public static Font getFontContactUs() {
        return FONT_CONTACT_US;
    }

    public static Font getFontButton() {
        return FONT_BUTTON;
    }

    public static byte[] merge(byte[]... pdfAsBytes) throws DocumentException, IOException {

        try (final ByteArrayOutputStream copyBaos = new ByteArrayOutputStream()) {
            final Document doc = new Document();
            final PdfCopy copy = new PdfSmartCopy(doc, copyBaos);

            doc.open();

            int numberOfPages = 0;
            final java.util.List<HashMap<String, Object>> bookmarks = new ArrayList<>();
            PdfReader pdf = null;
            for (byte[] pdfAsByte : pdfAsBytes) {

                if (pdfAsByte != null && pdfAsByte.length > 0) {
                    pdf = new PdfReader(pdfAsByte);
                    pdf.consolidateNamedDestinations();
                    final List<HashMap<String, Object>> pdfBookmarks = SimpleBookmark.getBookmark(pdf);
                    if (!CollectionUtils.isEmpty(pdfBookmarks)) {
                        SimpleBookmark.shiftPageNumbers(pdfBookmarks, numberOfPages, null);
                        bookmarks.addAll(pdfBookmarks);
                    }

                    for (int i = 1; i <= pdf.getNumberOfPages(); i++) {
                        copy.addPage(copy.getImportedPage(pdf, i));
                    }
                    numberOfPages += pdf.getNumberOfPages();
                }

            }
            if (pdf != null) {
                SimpleNamedDestination.getNamedDestination(pdf, false);
            }

            if (!CollectionUtils.isEmpty(bookmarks)) {
                copy.setOutlines(bookmarks);
            }

            copy.close();
            return copyBaos.toByteArray();
        }
    }

    public static int numberOfPages(byte[] fileToPrint) throws IOException {
        if (fileToPrint == null) {
            return 0;
        }

        return new PdfReader(fileToPrint.clone()).getNumberOfPages();
    }

    public static byte[] setPageNumbers(byte[] pdfDocument) throws IOException, DocumentException {

        final int numberOfPages = numberOfPages(pdfDocument);

        if (numberOfPages > 1) {

            try (final ByteArrayOutputStream baos = new ByteArrayOutputStream()) {

                final PdfReader reader = new PdfReader(pdfDocument);
                final PdfStamper stamper = new PdfStamper(reader, baos);

                for (int pageNumber = 2; pageNumber <= numberOfPages; pageNumber++) {
                    // get the first page
                    final PdfContentByte canvas = stamper.getOverContent(pageNumber);

                    // stamp the footer on the page
                    final ColumnText ct = new ColumnText(canvas);

                    ColumnText.showTextAligned(canvas, Element.ALIGN_CENTER,
                            new Phrase(pageNumber + "", getFontPageNumber()), 550, 22, 0);
                    ct.go();

                }

                // close out
                stamper.close();
                reader.close();

                return baos.toByteArray();

            }

        }

        return pdfDocument;

    }

    public static byte[] organize(byte[] pdf, Toc tableOfContents) throws IOException, DocumentException {

        try (final ByteArrayOutputStream copyBaos = new ByteArrayOutputStream()) {

            final Document doc = new Document();
            final PdfCopy copy = new PdfSmartCopy(doc, copyBaos);

            final PdfReader reader = new PdfReader(pdf);
            reader.selectPages(tableOfContents.getPageSequence());

            doc.open();

            for (int i = 1; i <= reader.getNumberOfPages(); i++) {
                copy.addPage(copy.getImportedPage(reader, i));
            }

            reader.close();
            copy.close();
            return copyBaos.toByteArray();
        }

    }

    public static byte[] emptyPage() throws DocumentException, IOException {

        try (final ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
            final Document document = createNewDocument();

            final PdfWriter pdfWriter = PdfWriter.getInstance(document, baos);
            document.open();
            document.newPage();
            pdfWriter.setPageEmpty(false);
            document.close();
            return baos.toByteArray();
        }
    }

    public static Document createNewDocument() {
        final Document document = new Document();
        document.setPageSize(PAGE_SIZE);
        document.setMargins(-10, -10, PAGE_MARGIN_TOP, PAGE_MARGIN_TOP);
        return document;
    }

    public static Image getImageFromPdf(byte[] pdf) throws IOException, BadElementException {

        try (final ByteArrayOutputStream bos = new ByteArrayOutputStream()) {

            final PdfReader reader = new PdfReader(pdf);
            final PdfReaderContentParser parser = new PdfReaderContentParser(reader);
            final ImageRenderListener listener = new ImageRenderListener(bos);

            parser.processContent(1, listener);

            reader.close();

            return Image.getInstance(bos.toByteArray());
        }

    }

    public static byte[] embedFont(byte[] pdf, String fontFileName, String fontName)
            throws IOException, DocumentException {

        try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
            // the font file
            RandomAccessFile raf = new RandomAccessFile(fontFileName, "r");
            byte fontfile[] = new byte[(int) raf.length()];
            raf.readFully(fontfile);
            raf.close();
            // create a new stream for the font file
            PdfStream stream = new PdfStream(fontfile);
            stream.flateCompress();
            stream.put(PdfName.LENGTH1, new PdfNumber(fontfile.length));
            // create a reader object
            PdfReader reader = new PdfReader(pdf);
            int n = reader.getXrefSize();
            PdfObject object;
            PdfDictionary font;
            PdfStamper stamper = new PdfStamper(reader, baos);
            PdfName fontname = new PdfName(fontName);
            for (int i = 0; i < n; i++) {
                object = reader.getPdfObject(i);
                if (object == null || !object.isDictionary())
                    continue;
                font = (PdfDictionary) object;
                if (PdfName.FONTDESCRIPTOR.equals(font.get(PdfName.TYPE1))
                        && fontname.equals(font.get(PdfName.FONTNAME))) {
                    PdfIndirectObject objref = stamper.getWriter().addToBody(stream);
                    font.put(PdfName.FONTFILE2, objref.getIndirectReference());
                }
            }
            stamper.close();
            reader.close();
            return baos.toByteArray();
        }
    }

    public static Image getImageFromByteArray(byte[] pdf) {
        try {
            return Image.getInstance(pdf);
        } catch (BadElementException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}