com.vigglet.pdf.PdfPage.java Source code

Java tutorial

Introduction

Here is the source code for com.vigglet.pdf.PdfPage.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.vigglet.pdf;

import java.awt.image.BufferedImage;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.util.Pair;
import javax.imageio.ImageIO;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.edit.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDTrueTypeFont;
import org.apache.pdfbox.pdmodel.graphics.xobject.PDJpeg;
import org.apache.pdfbox.pdmodel.graphics.xobject.PDXObjectImage;

/**
 *
 * @author vikn
 */
public class PdfPage {

    private List<PDPage> pages;
    private int pageNumber;
    private PDDocument doc;
    private PDPage page;
    private PDFont font;
    private PDRectangle rect;
    private PDPageContentStream contents;
    private float textHeight = 10f;
    private float informationTextHeight = 20f;
    private float headerHeight = 50f;
    private float currY;
    private float margin = 50f;
    private InputStream fontStream = PdfUtil.class
            .getResourceAsStream("/org/apache/pdfbox/resources/ttf/ArialMT.ttf");

    public PdfPage(PDDocument doc) {
        this.doc = doc;
        pages = new ArrayList<>();

        try {
            font = PDTrueTypeFont.loadTTF(doc, fontStream);
        } catch (IOException ex) {
            Logger.getLogger(PdfPage.class.getName()).log(Level.SEVERE, null, ex);
        }

        pageNumber = 1;
        addNewPage();
    }

    public void addNewPage() {
        currY = margin;
        page = getPage();
        rect = page.getMediaBox();
        try {
            contents = new PDPageContentStream(doc, page, true, true);
            contents.setFont(font, 10);
            contents.setLineWidth(0.5f);
            //            addCurrentPageNumber();
            //            contents.moveTo(rect.getUpperRightX(), rect.getUpperRightY());
        } catch (IOException ex) {
            Logger.getLogger(PdfPage.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private boolean newPageRequired() {
        return (rect.getHeight() - currY) <= 25;
    }

    private float getRemaningHeight() {
        return rect.getHeight() - (10 + currY);
    }

    public List<PDPage> getPDPages() {
        return pages;
    }

    public float getTextHeight() {
        return textHeight;
    }

    public void closeAndSave() throws IOException {
        if (page != null) {
            pages.add(page);
        }

        contents.saveGraphicsState();
        contents.close();
    }

    private void addCurrentPageNumber() throws IOException {
        contents.beginText();
        contents.setFont(font, 8);
        contents.moveTextPositionByAmount(rect.getUpperRightX() - 45, rect.getUpperRightY() - 20);
        contents.drawString("" + pageNumber++);
        contents.endText();
    }

    public void addTotalPageNumbers() throws IOException {
        int pageNumber = 1;
        for (PDPage bar : getPDPages()) {
            PDPageContentStream foo = new PDPageContentStream(doc, bar, true, true);

            foo.beginText();
            foo.setFont(font, 8);
            foo.moveTextPositionByAmount(rect.getUpperRightX() - 45, rect.getUpperRightY() - 20);
            foo.drawString("" + pageNumber++);
            foo.endText();

            foo.beginText();
            foo.setFont(font, 8);
            foo.moveTextPositionByAmount(rect.getUpperRightX() - 30, rect.getUpperRightY() - 20);
            foo.drawString("(" + pages.size() + ")");
            foo.endText();

            foo.saveGraphicsState();
            foo.close();
        }
    }

    private void log(String msg) {
        Logger.getLogger(getClass().getName()).log(Level.INFO, msg);
    }

    private float getNextTextLine() {
        return getNextLine(textHeight);
    }

    private float getNextInformationTextLine() {
        return getNextLine(informationTextHeight);
    }

    private float getNextHeaderLine() {
        return getNextLine(headerHeight);
    }

    private float getNextLine(float height) {
        //        return rect.getHeight() - height * (++line);
        currY += height;
        return rect.getHeight() - currY;
    }

    private PDPage getPage() {
        return getPage(PDPage.PAGE_SIZE_A4);
    }

    private PDPage getPage(PDRectangle pageSize) {
        return new PDPage(pageSize);
    }

    public void addHorizontalRow() throws IOException {
        addHorizontalRow(10);
    }

    public void addHorizontalRow(int margin) throws IOException {
        float y = getNextTextLine();
        contents.drawLine(margin, y, rect.getWidth() - margin, y);
    }

    public void addHeader(String header) throws IOException {
        contents.beginText();
        contents.setFont(font, 12);
        contents.moveTextPositionByAmount(margin, getNextHeaderLine());
        contents.drawString(header);
        contents.endText();
    }

    public void addPageHeader(String header) throws IOException {
        contents.beginText();
        contents.setFont(font, 24);
        contents.moveTextPositionByAmount(margin, getNextHeaderLine());
        contents.drawString(header);
        contents.endText();
    }

    protected void addTextBox(String title, String textContent) throws IOException {
        long startMs = System.currentTimeMillis();

        float xStart = margin;
        float xEnd = rect.getWidth() - margin;
        float width = rect.getWidth() - ((margin + 30) * 2);
        float y = getNextHeaderLine();
        float topY = y + 20f;
        float boxHeight = 0;

        contents.drawLine(xStart, (y + 20), xEnd, (y + 20));//Top line
        boxHeight += 20f;

        //Add the header
        contents.beginText();
        contents.setFont(font, 12);
        contents.moveTextPositionByAmount(margin + 10, y);
        contents.drawString(title);
        contents.endText();

        y = getNextLine(10);
        boxHeight += 10f;

        float stringWidth = font.getStringWidth(textContent) / 1000 * 10;
        float charWidth = stringWidth / textContent.length();
        int maxCharPerRow = 0;
        while ((maxCharPerRow * charWidth) <= width) {
            maxCharPerRow++;
        }

        contents.setFont(font, 10);

        int currCharIndex = 0;
        while (currCharIndex <= textContent.length()) {
            y = getNextTextLine();

            contents.beginText();
            contents.moveTextPositionByAmount(margin + 20, y);
            contents.drawString(textContent.substring(currCharIndex,
                    ((currCharIndex + maxCharPerRow) >= textContent.length() ? textContent.length()
                            : (currCharIndex + maxCharPerRow))));
            contents.endText();

            boxHeight += textHeight;
            currCharIndex += maxCharPerRow;
        }

        y = getNextTextLine();
        boxHeight += textHeight;
        contents.drawLine(xStart, topY, xStart, topY - boxHeight);//Left line
        contents.drawLine(xEnd, topY, xEnd, topY - boxHeight);//Right line
        contents.drawLine(xStart, y, xEnd, y);//Bottom line

        long endMs = System.currentTimeMillis();
        log("Drew textbox in " + (endMs - startMs) + " ms (" + (endMs - startMs) / 1000 + " s)");
    }

    public void addInformationHeaders(List<Pair<String, String>> defaultHeaders, List<Pair<String, String>> headers)
            throws IOException {
        List<Pair<String, String>> informationHeaders = new ArrayList<>((defaultHeaders.size() + headers.size()));
        informationHeaders.addAll(defaultHeaders);
        informationHeaders.addAll(headers);

        contents.setFont(font, 12);
        float y = getNextHeaderLine();
        y = getNextHeaderLine();
        float spacing = 80;
        float x = margin;
        float yTemp = y;

        int i = 0;
        for (Pair<String, String> pair : informationHeaders) {
            //header
            contents.beginText();
            contents.moveTextPositionByAmount(x, yTemp);
            contents.drawString(pair.getKey() + ":");
            contents.endText();
            //value
            contents.beginText();
            contents.moveTextPositionByAmount(x + spacing, yTemp);
            contents.drawString(pair.getValue());
            contents.endText();
            yTemp += 20f;

            //Reset to top again
            if (i++ == 2) {
                //                x = (rect.getWidth() - (margin * 2)) / 2;
                x = rect.getWidth() / 2;
                yTemp = y;
            }
        }
    }

    public void drawTable(String header, List<String> headers, List<List<String>> rows) throws IOException {
        long startMs = System.currentTimeMillis();

        float xStart = margin;
        float xEnd = rect.getWidth() - margin;
        //        float height = (float) ((rows.size() + 1) * (10 + 5));
        float y = getNextHeaderLine();
        contents.setLineWidth(0.5f);

        //Add the header
        contents.beginText();
        contents.setFont(font, 12);
        contents.moveTextPositionByAmount(margin + 10, y);
        contents.drawString(header);
        contents.endText();

        y = getNextLine(10);

        contents.drawLine(xStart, y, xEnd, y);//Line above column names
        contents.setFont(font, 10);
        //        contents.drawLine(xStart, y, xEnd, y);//Top line
        //        contents.drawLine(xStart, y, xStart, y - height);//Left line
        //        contents.drawLine(xEnd, y, xEnd, y - height);//Right line
        //Headers
        float x = margin;
        float columnWidth = (rect.getWidth() - 100) / headers.size();
        addHeaders(headers, y, x, columnWidth);

        y = getNextLine(5);
        contents.drawLine(xStart, y, xEnd, y);
        y = getNextLine(5);
        //Table
        //        x = margin;
        for (List<String> row : rows) {
            if (newPageRequired()) {
                closeAndSave();
                addNewPage();

                y = getNextLine(25);
                contents.drawLine(xStart, y, xEnd, y);//Top line
                addHeaders(headers, y, x, columnWidth);
                y = getNextLine(5);
                contents.drawLine(xStart, y, xEnd, y);
                y = getNextLine(5);
            }

            y = getNextTextLine();
            for (String str : row) {
                float stringWidth = font.getStringWidth(str) / 1000 * 10;
                if (stringWidth > columnWidth) {
                    float charWidth = stringWidth / (str.length() - 5);
                    int charCount = 0;
                    while ((charCount * charWidth) <= columnWidth) {
                        charCount++;
                    }

                    str = str.substring(0, charCount) + "...";
                }

                contents.beginText();
                contents.moveTextPositionByAmount(x + 2, y);
                contents.drawString(str);
                contents.endText();

                //                contents.drawLine(x, y + textHeight, x, y - 5);
                //                contents.drawLine(x + columnWidth, y + textHeight, x + columnWidth, y - 5);
                x += columnWidth;
            }
            y = getNextLine(7);

            //            contents.drawLine(xStart, y, xEnd, y);
            x = margin;
        }
        long endMs = System.currentTimeMillis();
        log("Drew table in " + (endMs - startMs) + " ms (" + (endMs - startMs) / 1000 + " s)");
    }

    private void addHeaders(List<String> headers, float y, float x, float columnWidth) throws IOException {
        y = getNextTextLine();
        for (String head : headers) {
            contents.beginText();
            contents.moveTextPositionByAmount(x + 2, y);
            contents.drawString(head.trim());
            contents.endText();

            //            contents.drawLine(x, y + textHeight, x, y - 5);
            //            contents.drawLine(x + columnWidth, y + textHeight, x + columnWidth, y - 5);;
            x += columnWidth;
        }
    }

    public void addTextBox(PDRectangle rect, int line, String header, List<String> values) throws IOException {
        float xStart = margin;
        float xEnd = rect.getWidth() - margin;
        float height = (float) (values.size() * 10.2);
        float y = getNextHeaderLine();

        //Add the header
        contents.beginText();
        contents.setFont(font, 8);
        contents.moveTextPositionByAmount(margin + 10, y);
        contents.drawString(header);
        contents.endText();

        y = getNextLine(5);

        contents.drawLine(xStart, y, xEnd, y);//Top line
        contents.drawLine(xStart, y, xStart, y - height);//Left line
        contents.drawLine(xEnd, y, xEnd, y - height);//Right line
        contents.drawLine(xStart, y - height, xEnd, y - height);//Bottom line

        //Fill the box
        float contentBoxTextX = margin + 2;
        for (String str : values) {
            contents.beginText();
            contents.moveTextPositionByAmount(contentBoxTextX, getNextTextLine());
            contents.drawString(str.trim() + ".");
            contents.endText();
        }
    }

    public void addLogo(FileInputStream fis) throws IOException {
        //        PDDocument document = new PDDocument();

        BufferedImage bimg = ImageIO.read(fis);
        float width = bimg.getWidth();
        float height = bimg.getHeight();
        //        PDPage page = new PDPage(new PDRectangle(width, height));
        //        document.addPage(page);

        //        PDXObjectImage img = new PDJpeg(document, new FileInputStream(someImage));
        PDXObjectImage img = new PDJpeg(doc, fis);
        //        PDPageContentStream contentStream = new PDPageContentStream(doc, page);
        contents.drawImage(img, margin, currY);
        //        contentStream.close();
        fis.close();
    }

}