Java tutorial
/* * 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(); } }