started API clean up

This commit is contained in:
jomu
2016-06-15 10:42:27 +00:00
parent a9da425681
commit 1cd84cfa3b
25 changed files with 495 additions and 318 deletions

View File

@ -0,0 +1,14 @@
package de.muehlencord.shared.pdf;
/**
*
* @author joern.muehlencord
*/
public abstract class CellValue {
public abstract int getColSize();
public abstract float getCellPadding();
}

View File

@ -9,7 +9,7 @@ import org.apache.pdfbox.pdmodel.common.PDRectangle;
* *
* @author jomu * @author jomu
*/ */
public abstract class Content { abstract class Content {
protected PDFDocument document; protected PDFDocument document;
protected PDRectangle rect; protected PDRectangle rect;

View File

@ -4,7 +4,7 @@ package de.muehlencord.shared.pdf;
* *
* @author joern.muehlencord * @author joern.muehlencord
*/ */
public class Coordinate { class Coordinate {
final float x; final float x;
final float y; final float y;

View File

@ -8,10 +8,13 @@ import java.util.List;
* *
* @author joern.muehlencord * @author joern.muehlencord
*/ */
public class DefaultTableRow extends TableRow { class DefaultTableRow extends TableRow {
@Expose @Expose
private final List<Text> row; private final List<TextElement> row;
@Expose
private final List<Float> padding;
@Expose @Expose
private Boolean isList; private Boolean isList;
@ -22,50 +25,73 @@ public class DefaultTableRow extends TableRow {
@Expose @Expose
private String varName; private String varName;
public DefaultTableRow() { protected DefaultTableRow() {
this.row = new ArrayList<>(); this.row = new ArrayList<>();
this.padding = new ArrayList<>();
this.isList = false; this.isList = false;
this.listName = null; this.listName = null;
this.varName = null; this.varName = null;
} }
@Override
protected void addColumn(TextElement element) {
row.add(element);
padding.add(null);
}
public void add(Text text) { @Override
row.add(text); protected void addColumn(TextElement element, Float p) {
row.add(element);
padding.add(p);
} }
/* *** TableRow methods *** */ /* *** TableRow methods *** */
@Override @Override
public int getColumnCount() { protected int getColumnCount() {
return row.size(); return row.size();
} }
@Override @Override
public Text getColumnValue(int columnPos) { protected String getColumnValue(int columnPos) {
return row.get(columnPos); return row.get(columnPos).getText();
} }
@Override @Override
public boolean isList() { protected PDFTextAlignment getAlignment(int columnPos) {
return row.get(columnPos).getAlign();
}
@Override
protected Float getCellPadding(int columnPos) {
Float currentPadding = padding.get(columnPos);
if (currentPadding == null) {
return 0F;
} else {
return currentPadding ;
}
}
@Override
protected boolean isList() {
return isList; return isList;
} }
@Override @Override
public void createList(String listName, String varName) { protected DefaultTableRow createList(String listName, String varName) {
this.listName = listName; this.listName = listName;
this.varName = varName; this.varName = varName;
this.isList = true; this.isList = true;
return this;
} }
@Override @Override
public String getListName() { protected String getListName() {
return listName; return listName;
} }
@Override @Override
public String getVarName() { protected String getVarName() {
return varName; return varName;
} }
} }

View File

@ -7,7 +7,7 @@ import com.google.gson.GsonBuilder;
* *
* @author jomu * @author jomu
*/ */
public class GsonUtil { class GsonUtil {
protected final static Gson getGsonInstance() { protected final static Gson getGsonInstance() {
return new GsonBuilder() return new GsonBuilder()
@ -15,6 +15,7 @@ public class GsonUtil {
.excludeFieldsWithoutExposeAnnotation() .excludeFieldsWithoutExposeAnnotation()
.registerTypeAdapter(Content.class, new InterfaceAdapter<>()) .registerTypeAdapter(Content.class, new InterfaceAdapter<>())
.registerTypeAdapter(TableRow.class, new InterfaceAdapter<>()) .registerTypeAdapter(TableRow.class, new InterfaceAdapter<>())
.registerTypeAdapter(CellValue.class, new InterfaceAdapter<>())
.create(); .create();
} }

View File

@ -1,105 +0,0 @@
package de.muehlencord.shared.pdf;
import com.google.gson.annotations.Expose;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import javax.imageio.ImageIO;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.graphics.image.LosslessFactory;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
/**
*
* @author joern.muehlencord
*/
public class ImageContent extends Content {
@Expose
private Float scale = null;
@Expose
private String base64CodedImage = null;
public ImageContent(PDFDocument document, String contentString) throws IOException {
super(document);
this.base64CodedImage = contentString;
}
public ImageContent(PDFDocument document, File file) throws IOException {
super(document);
this.base64CodedImage = getEncodedString(ImageIO.read(file));
}
public ImageContent(PDFDocument document, BufferedImage img) throws IOException {
super(document);
this.base64CodedImage = getEncodedString(img);
}
public ImageContent(PDFDocument document, Float x, Float y, String contentString) throws IOException {
super(document, x, y);
this.base64CodedImage = contentString;
}
public ImageContent(PDFDocument document, Float x, Float y, File file) throws IOException {
super(document, x, y);
this.base64CodedImage = getEncodedString(ImageIO.read(file));
}
public ImageContent(PDFDocument document, Float x, Float y, BufferedImage img) throws IOException {
super(document, x, y);
this.base64CodedImage = getEncodedString(img);
}
public ImageContent(PDFDocument document, Float x, Float y, Float scale, String contentString) throws IOException {
super(document, x, y);
this.scale = scale;
this.base64CodedImage = contentString;
}
public ImageContent(PDFDocument document, Float x, Float y, Float scale, File file) throws IOException {
super(document, x, y);
this.scale = scale;
this.base64CodedImage = getEncodedString(ImageIO.read(file));
}
public ImageContent(PDFDocument document, Float x, Float y, Float scale, BufferedImage img) throws IOException {
super(document, x, y);
this.scale = scale;
this.base64CodedImage = getEncodedString(img);
}
@Override
protected Coordinate addContentToPdf(PDPageContentStream cos) throws IOException, ConfigurationException {
BufferedImage image = getImage();
PDImageXObject pdImage = LosslessFactory.createFromImage(document.getPdDocument(), image);
float height = pdImage.getHeight() * getScale();
float width = pdImage.getWidth() * getScale();
cos.drawImage(pdImage, x, y, width, height);
return new Coordinate(x, y - height);
}
private String getEncodedString(BufferedImage img) throws IOException {
final ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageIO.write(img, "png", Base64.getEncoder().wrap(os));
return os.toString(StandardCharsets.UTF_8.name());
}
private BufferedImage getImage() throws IOException {
return ImageIO.read(new ByteArrayInputStream(Base64.getDecoder().decode(this.base64CodedImage)));
}
/* *** getter / setter */
public Float getScale() {
if (scale == null) {
return 1F;
} else {
return scale;
}
}
}

View File

@ -13,7 +13,7 @@ import com.google.gson.JsonSerializer;
* *
* @author jomu * @author jomu
*/ */
public class InterfaceAdapter<T> implements JsonSerializer<T>, JsonDeserializer<T> { class InterfaceAdapter<T> implements JsonSerializer<T>, JsonDeserializer<T> {
@Override @Override
public final JsonElement serialize(final T object, final Type interfaceType, final JsonSerializationContext context) { public final JsonElement serialize(final T object, final Type interfaceType, final JsonSerializationContext context) {

View File

@ -4,7 +4,7 @@ package de.muehlencord.shared.pdf;
* *
* @author joern.muehlencord * @author joern.muehlencord
*/ */
public interface ListTemplate { interface ListTemplate {
public void createList (String listName, String varName); public void createList (String listName, String varName);

View File

@ -17,13 +17,13 @@ import org.apache.pdfbox.pdmodel.font.PDType1Font;
public class PDFDocument { public class PDFDocument {
@Expose @Expose
private PaperSize paperSize; private PDFPaperSize paperSize;
@Expose @Expose
protected Font standardFont; protected PDFFont standardFont;
@Expose @Expose
protected Map<String, Font> fontMap; protected Map<String, PDFFont> fontMap;
@Expose @Expose
private final List<Content> contentList; private final List<Content> contentList;
@ -32,7 +32,7 @@ public class PDFDocument {
public PDFDocument() { public PDFDocument() {
this.contentList = new ArrayList<>(); this.contentList = new ArrayList<>();
this.standardFont = new Font("Helvetica", 11); this.standardFont = new PDFFont("Helvetica", 11);
this.fontMap = null; this.fontMap = null;
} }
@ -115,7 +115,7 @@ public class PDFDocument {
return templateString; return templateString;
} }
public void addFont(String name, Font font) { public void addFont(String name, PDFFont font) {
if (fontMap == null) { if (fontMap == null) {
fontMap = new ConcurrentHashMap<>(); fontMap = new ConcurrentHashMap<>();
} }
@ -132,7 +132,7 @@ public class PDFDocument {
} }
} }
public Font getFontByAlias(String fontAlias) throws ConfigurationException { public PDFFont getFontByAlias(String fontAlias) throws ConfigurationException {
if ((fontMap != null) && (fontMap.containsKey(fontAlias))) { if ((fontMap != null) && (fontMap.containsKey(fontAlias))) {
return fontMap.get(fontAlias); return fontMap.get(fontAlias);
} else { } else {
@ -146,19 +146,19 @@ public class PDFDocument {
} }
/* *** getter / setter *** */ /* *** getter / setter *** */
public PaperSize getPaperSize() { public PDFPaperSize getPaperSize() {
return paperSize; return paperSize;
} }
public void setPaperSize(PaperSize paperSize) { public void setPaperSize(PDFPaperSize paperSize) {
this.paperSize = paperSize; this.paperSize = paperSize;
} }
public Font getStandardFont() { public PDFFont getStandardFont() {
return standardFont; return standardFont;
} }
public void setStandardFont(Font standardFont) { public void setStandardFont(PDFFont standardFont) {
this.standardFont = standardFont; this.standardFont = standardFont;
} }

View File

@ -1,9 +0,0 @@
package de.muehlencord.shared.pdf;
/**
*
* @author joern.muehlencord
*/
public class PDFElement {
}

View File

@ -6,7 +6,7 @@ import com.google.gson.annotations.Expose;
* *
* @author jomu * @author jomu
*/ */
public class Font { public class PDFFont {
@Expose @Expose
private String fontName; private String fontName;
@ -15,13 +15,13 @@ public class Font {
@Expose @Expose
private int padding; private int padding;
public Font(String fontName, int fontSize) { public PDFFont(String fontName, int fontSize) {
this.fontName = fontName; this.fontName = fontName;
this.fontSize = fontSize; this.fontSize = fontSize;
this.padding = 2; this.padding = 2;
} }
public Font(String fontName, int fontSize, int padding) { public PDFFont(String fontName, int fontSize, int padding) {
this.fontName = fontName; this.fontName = fontName;
this.fontSize = fontSize; this.fontSize = fontSize;
this.padding = padding; this.padding = padding;

View File

@ -0,0 +1,91 @@
package de.muehlencord.shared.pdf;
import com.google.gson.annotations.Expose;
import de.muehlencord.shared.pdf.util.ImageUtil;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.graphics.image.LosslessFactory;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
/**
*
* @author joern.muehlencord
*/
public class PDFImageContent extends Content {
@Expose
private Float scale = null;
@Expose
private String base64CodedImage = null;
public PDFImageContent(PDFDocument document, String contentString) throws IOException {
super(document);
this.base64CodedImage = contentString;
}
public PDFImageContent(PDFDocument document, File file) throws IOException {
super(document);
this.base64CodedImage = ImageUtil.getEncodedString(ImageIO.read(file));
}
public PDFImageContent(PDFDocument document, BufferedImage img) throws IOException {
super(document);
this.base64CodedImage = ImageUtil.getEncodedString(img);
}
public PDFImageContent(PDFDocument document, Float x, Float y, String contentString) throws IOException {
super(document, x, y);
this.base64CodedImage = contentString;
}
public PDFImageContent(PDFDocument document, Float x, Float y, File file) throws IOException {
super(document, x, y);
this.base64CodedImage = ImageUtil.getEncodedString(ImageIO.read(file));
}
public PDFImageContent(PDFDocument document, Float x, Float y, BufferedImage img) throws IOException {
super(document, x, y);
this.base64CodedImage = ImageUtil.getEncodedString(img);
}
public PDFImageContent(PDFDocument document, Float x, Float y, Float scale, String contentString) throws IOException {
super(document, x, y);
this.scale = scale;
this.base64CodedImage = contentString;
}
public PDFImageContent(PDFDocument document, Float x, Float y, Float scale, File file) throws IOException {
super(document, x, y);
this.scale = scale;
this.base64CodedImage = ImageUtil.getEncodedString(ImageIO.read(file));
}
public PDFImageContent(PDFDocument document, Float x, Float y, Float scale, BufferedImage img) throws IOException {
super(document, x, y);
this.scale = scale;
this.base64CodedImage = ImageUtil.getEncodedString(img);
}
@Override
protected Coordinate addContentToPdf(PDPageContentStream cos) throws IOException, ConfigurationException {
BufferedImage image = ImageUtil.getImageFromEncodedString(base64CodedImage);
PDImageXObject pdImage = LosslessFactory.createFromImage(document.getPdDocument(), image);
float height = pdImage.getHeight() * getScale();
float width = pdImage.getWidth() * getScale();
cos.drawImage(pdImage, x, y, width, height);
return new Coordinate(x, y - height);
}
/* *** getter / setter */
public Float getScale() {
if (scale == null) {
return 1F;
} else {
return scale;
}
}
}

View File

@ -9,13 +9,13 @@ package de.muehlencord.shared.pdf;
* *
* @author jomu * @author jomu
*/ */
public enum PaperSize { public enum PDFPaperSize {
A4("A4"); A4("A4");
private String label; private String label;
private PaperSize(String label) { private PDFPaperSize(String label) {
this.label = label; this.label = label;
} }

View File

@ -4,6 +4,7 @@ import com.google.gson.annotations.Expose;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import org.apache.pdfbox.pdmodel.PDPageContentStream; import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDFont; import org.apache.pdfbox.pdmodel.font.PDFont;
@ -14,12 +15,12 @@ import org.slf4j.LoggerFactory;
* *
* @author jomu * @author jomu
*/ */
public class TableContent extends Content { public class PDFTableContent extends Content {
private static final Logger LOGGER = LoggerFactory.getLogger(TableContent.class); private static final Logger LOGGER = LoggerFactory.getLogger(PDFTableContent.class);
@Expose @Expose
private final Font headerFont; private final PDFFont headerFont;
@Expose @Expose
private final TableHeader header; private final TableHeader header;
@ -27,45 +28,69 @@ public class TableContent extends Content {
@Expose @Expose
private List<TableRow> data = null; private List<TableRow> data = null;
public TableContent(PDFDocument doc, Font hf) { public PDFTableContent(PDFDocument doc, PDFFont hf) {
super(doc); super(doc);
this.header = new TableHeader(); this.header = new TableHeader();
this.headerFont = hf; this.headerFont = hf;
this.data = new ArrayList<>(); this.data = new LinkedList<>();
} }
public TableContent(PDFDocument doc, Font hf, int x, int y) { public PDFTableContent(PDFDocument doc, PDFFont hf, int x, int y) {
super(doc, x, y); super(doc, x, y);
this.header = new TableHeader(); this.header = new TableHeader();
this.headerFont = hf; this.headerFont = hf;
this.data = new ArrayList<>(); this.data = new ArrayList<>();
} }
public DefaultTableRow addLine(String... values) { public PDFTableContent addRow() {
return addLine(Arrays.asList(values)); DefaultTableRow newRow = new DefaultTableRow();
data.add(newRow);
return this;
} }
public DefaultTableRow addLine(List<String> values) { public PDFTableContent addListRow(String listName, String varName) {
DefaultTableRow newRow = new DefaultTableRow();
newRow.createList(listName, varName);
data.add(newRow);
return this;
}
public PDFTableContent addRow(String... values) throws ConfigurationException {
return addRow(Arrays.asList(values));
}
public PDFTableContent addRow(List<String> values) throws ConfigurationException {
DefaultTableRow newLine = new DefaultTableRow(); DefaultTableRow newLine = new DefaultTableRow();
values.stream().forEach((cellText) -> {
newLine.add(new Text(cellText));
});
data.add(newLine); data.add(newLine);
return newLine; for (String cellText : values) {
addColumn (cellText);
}
return this;
} }
public DefaultTableRow addTextLine(Text... values) { public PDFTableContent addColumn(String text) throws ConfigurationException {
return addTextLine(Arrays.asList(values)); if (data.isEmpty()) {
throw new ConfigurationException ("Need to call newRow first");
}
data.get(data.size()-1).addColumn(new TextElement (text));
return this;
} }
public DefaultTableRow addTextLine(List<Text> values) { public PDFTableContent addColumn(String text, PDFTextAlignment alignment) throws ConfigurationException {
DefaultTableRow newLine = new DefaultTableRow(); if (data.isEmpty()) {
values.stream().forEach((text) -> { throw new ConfigurationException ("Need to call newRow first");
newLine.add(text); }
}); data.get(data.size()-1).addColumn(new TextElement (text, alignment));
data.add(newLine); return this;
return newLine; }
public PDFTableContent addColumn(String text, PDFTextAlignment alignment, Float padding) throws ConfigurationException {
if (data.isEmpty()) {
throw new ConfigurationException ("Need to call newRow first");
}
data.get(data.size()-1).addColumn(new TextElement (text, alignment), padding);
return this;
} }
protected TableRow getRow(int no) { protected TableRow getRow(int no) {
@ -93,21 +118,22 @@ public class TableContent extends Content {
cos.setFont(hFont, headerFont.getFontSize()); cos.setFont(hFont, headerFont.getFontSize());
cos.newLineAtOffset(x, y); cos.newLineAtOffset(x, y);
for (int i = 0; i < header.size(); i++) { for (int i = 0; i < header.size(); i++) {
Text currentHeader = header.getHeader(i); String headerText = header.getHeader(i);
PDFTextAlignment currentAlignment = header.getAlignment(i);
float cellPadding = header.getCellPadding(i); float cellPadding = header.getCellPadding(i);
float startX; float startX;
if (currentHeader.getAlign() == TextAlignment.RIGHT) { if (currentAlignment == PDFTextAlignment.RIGHT) {
float textWdith = (standardFont.getStringWidth(currentHeader.getText()) / 1000F) * document.getStandardFont().getFontSize(); float textWdith = (standardFont.getStringWidth(headerText) / 1000F) * document.getStandardFont().getFontSize();
float width = header.getColumnSize(i) - 2 * cellPadding; float width = header.getColumnSize(i) - (2F * cellPadding);
startX = width - textWdith; startX = width - textWdith;
cos.newLineAtOffset(startX, 0); cos.newLineAtOffset(startX, 0);
} else { } else {
startX = 0; startX = 0;
} }
cos.showText(currentHeader.getText()); cos.showText(headerText);
cos.newLineAtOffset(header.getColumnSize(i) - startX, 0); cos.newLineAtOffset(header.getColumnSize(i) - startX, 0);
} }
if (data.isEmpty()) { if (data.isEmpty()) {
@ -120,22 +146,23 @@ public class TableContent extends Content {
cos.newLineAtOffset(xOffSet, yOffset); cos.newLineAtOffset(xOffSet, yOffset);
currentY += yOffset; currentY += yOffset;
for (int colNo = 0; colNo < currentRow.getColumnCount(); colNo++) { for (int colNo = 0; colNo < currentRow.getColumnCount(); colNo++) {
Text currentColText = currentRow.getColumnValue(colNo); String currentColText = currentRow.getColumnValue(colNo);
float cellPadding = header.getCellPadding(colNo); PDFTextAlignment currentColAlignment = currentRow.getAlignment(colNo);
float cellPadding = currentRow.getCellPadding(colNo);
float startX; float startX;
// FIXME duplication with header and textContent object // FIXME duplication with header and textContent object
if (currentColText.getAlign() == TextAlignment.RIGHT) { if (currentColAlignment == PDFTextAlignment.RIGHT) {
float textWdith = (standardFont.getStringWidth(currentColText.getText()) / 1000F) * document.getStandardFont().getFontSize(); float textWdith = (standardFont.getStringWidth(currentColText) / 1000F) * document.getStandardFont().getFontSize();
float width = header.getColumnSize(colNo) - 2 * cellPadding; float width = header.getColumnSize(colNo) - (2F * cellPadding);
startX = width - textWdith; startX = width - textWdith;
LOGGER.info("Text width for {} = {}", currentColText.getText(), textWdith); LOGGER.info("Text width for {} = {}", currentColText, textWdith);
cos.newLineAtOffset(startX, 0); cos.newLineAtOffset(startX, 0);
} else { } else {
startX = 0; startX = 0;
} }
cos.showText(currentColText.getText()); cos.showText(currentColText);
cos.newLineAtOffset(header.getColumnSize(colNo) - startX, 0); cos.newLineAtOffset(header.getColumnSize(colNo) - startX, 0);
} }
} }
@ -147,7 +174,7 @@ public class TableContent extends Content {
} }
/* *** getter / setter *** */ /* *** getter / setter *** */
public Font getHeaderFont() { public PDFFont getHeaderFont() {
return headerFont; return headerFont;
} }

View File

@ -3,12 +3,10 @@ package de.muehlencord.shared.pdf;
import com.google.gson.Gson; import com.google.gson.Gson;
import freemarker.template.Template; import freemarker.template.Template;
import freemarker.template.TemplateException; import freemarker.template.TemplateException;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.StringWriter; import java.io.StringWriter;
import java.io.Writer; import java.io.Writer;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.io.FileUtils;
import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream; import org.apache.pdfbox.pdmodel.PDPageContentStream;
@ -67,7 +65,7 @@ public class PDFTemplate {
Coordinate coord = null; Coordinate coord = null;
for (Content content : pdfDoc.getContentList()) { for (Content content : pdfDoc.getContentList()) {
content.setDocument(pdfDoc); // FIXME move to serialization content.setDocument(pdfDoc); // FIXME move to serialization
content.setRect (page.getMediaBox()); content.setRect(page.getMediaBox());
content.setCoordinate(coord); content.setCoordinate(coord);
coord = content.addContentToPdf(cos); coord = content.addContentToPdf(cos);
} }

View File

@ -4,7 +4,7 @@ package de.muehlencord.shared.pdf;
* *
* @author joern.muehlencord * @author joern.muehlencord
*/ */
public enum TextAlignment { public enum PDFTextAlignment {
LEFT, LEFT,
RIGHT; RIGHT;

View File

@ -11,44 +11,44 @@ import org.apache.pdfbox.pdmodel.font.PDFont;
* *
* @author jomu * @author jomu
*/ */
public class TextContent extends Content { public class PDFTextContent extends Content {
@Expose @Expose
private final List<Text> textLines; private final List<TextElement> textLines;
public TextContent(PDFDocument doc) { public PDFTextContent(PDFDocument doc) {
super(doc); super(doc);
this.textLines = new LinkedList<>(); this.textLines = new LinkedList<>();
} }
public TextContent(PDFDocument doc, Float x, Float y) { public PDFTextContent(PDFDocument doc, Float x, Float y) {
super(doc, x, y); super(doc, x, y);
this.textLines = new LinkedList<>(); this.textLines = new LinkedList<>();
} }
public TextContent(PDFDocument doc, Float x, Float y, String text) { public PDFTextContent(PDFDocument doc, Float x, Float y, String text) {
super(doc, x, y); super(doc, x, y);
this.textLines = new LinkedList<>(); this.textLines = new LinkedList<>();
this.textLines.add(new Text(text)); this.textLines.add(new TextElement(text));
} }
public TextContent addLine() { public PDFTextContent addLine() {
this.textLines.add(new Text()); this.textLines.add(new TextElement());
return this; return this;
} }
public TextContent addLine(String text) { public PDFTextContent addLine(String text) {
this.textLines.add(new Text(text)); this.textLines.add(new TextElement(text));
return this; return this;
} }
public TextContent addLine(String text, TextAlignment align) { public PDFTextContent addLine(String text, PDFTextAlignment align) {
this.textLines.add(new Text(text, align)); this.textLines.add(new TextElement(text, align));
return this; return this;
} }
public TextContent addLine(String text, String fontAlias) { public PDFTextContent addLine(String text, String fontAlias) {
this.textLines.add(new Text(text, fontAlias)); this.textLines.add(new TextElement(text, fontAlias));
return this; return this;
} }
@ -59,13 +59,13 @@ public class TextContent extends Content {
cos.beginText(); cos.beginText();
cos.newLineAtOffset(x, y); cos.newLineAtOffset(x, y);
float currentY = y; float currentY = y;
for (Text textLine : textLines) { for (TextElement textLine : textLines) {
Font font = (textLine.getFontAlias() == null ? document.getStandardFont() : document.getFontByAlias(textLine.getFontAlias())); PDFFont font = (textLine.getFontAlias() == null ? document.getStandardFont() : document.getFontByAlias(textLine.getFontAlias()));
PDFont pdFont = document.getFont(font.getFontName()); PDFont pdFont = document.getFont(font.getFontName());
cos.setFont(pdFont, font.getFontSize()); cos.setFont(pdFont, font.getFontSize());
int leading = font.getFontSize() + font.getPadding(); int leading = font.getFontSize() + font.getPadding();
if (textLine.getAlign() == TextAlignment.RIGHT) { if (textLine.getAlign() == PDFTextAlignment.RIGHT) {
float textWdith = (pdFont.getStringWidth(textLine.getText()) / 1000F) * font.getFontSize(); float textWdith = (pdFont.getStringWidth(textLine.getText()) / 1000F) * font.getFontSize();
float width = rect.getUpperRightX() - rect.getLowerLeftX() - 2 * margin; float width = rect.getUpperRightX() - rect.getLowerLeftX() - 2 * margin;
float startX = width - textWdith; float startX = width - textWdith;

View File

@ -11,72 +11,64 @@ import java.util.List;
public class TableHeader { public class TableHeader {
@Expose @Expose
private final List<Text> headers; private final List<CellValue> headerCells;
@Expose
private final List<Integer> colSizes;
@Expose
private final List<Float> cellPadding;
public TableHeader() { public TableHeader() {
headers = new ArrayList<>(); headerCells = new ArrayList<>();
colSizes = new ArrayList<>();
cellPadding = new ArrayList<>();
}
public TableHeader add(Text header, int colSize) {
headers.add(header);
colSizes.add(colSize);
cellPadding.add(null);
return this;
} }
public TableHeader add(String headerText, int colSize) { public TableHeader add(String headerText, int colSize) {
headers.add(new Text(headerText)); headerCells.add (new TextCellValue (headerText, colSize));
colSizes.add(colSize);
cellPadding.add(null);
return this; return this;
} }
public TableHeader add(String headerText, int colSize, Float padding) { public TableHeader add(String headerText, int colSize, Float padding) {
headers.add(new Text(headerText)); headerCells.add (new TextCellValue (headerText, colSize));
colSizes.add(colSize);
cellPadding.add(padding);
return this; return this;
} }
public TableHeader add(String headerText, int colSize, TextAlignment align) { public TableHeader add(String headerText, int colSize, PDFTextAlignment align) {
headers.add(new Text(headerText, align)); headerCells.add (new TextCellValue (headerText, colSize, align));
colSizes.add(colSize);
cellPadding.add(null);
return this; return this;
} }
public TableHeader add(String headerText, int colSize, TextAlignment align, float padding) { public TableHeader add(String headerText, int colSize, PDFTextAlignment align, float padding) {
headers.add(new Text(headerText, align)); headerCells.add (new TextCellValue (headerText, colSize, align, padding));
colSizes.add(colSize);
cellPadding.add(padding);
return this; return this;
} }
/* *** getter *** */ /* *** getter *** */
public int size() { public int size() {
return headers.size(); return headerCells.size();
} }
public int getColumnSize(int pos) { public int getColumnSize(int pos) {
return colSizes.get(pos); return headerCells.get(pos).getColSize();
} }
public Text getHeader(int pos) { public String getHeader(int pos) throws ConfigurationException {
return headers.get(pos); CellValue header = headerCells.get(pos);
if (header instanceof TextCellValue) {
TextCellValue textHeader = (TextCellValue) header;
return textHeader.getCellText();
} else {
return "Unsupported";
}
}
public PDFTextAlignment getAlignment (int pos) {
CellValue header = headerCells.get(pos);
if (header instanceof TextCellValue) {
TextCellValue textHeader = (TextCellValue) header;
return textHeader.getAlignment();
} else {
return null;
}
} }
public Float getCellPadding(int pos) { public Float getCellPadding(int pos) {
if (cellPadding.get(pos) == null) { return headerCells.get(pos).getCellPadding();
return 0F;
} else {
return cellPadding.get(pos);
}
} }
} }

View File

@ -4,18 +4,27 @@ package de.muehlencord.shared.pdf;
* *
* @author joern.muehlencord * @author joern.muehlencord
*/ */
public abstract class TableRow { abstract class TableRow {
public abstract int getColumnCount(); protected abstract TableRow createList(String listName, String varName);
public abstract void createList(String listName, String varName); protected abstract int getColumnCount();
public abstract boolean isList(); protected abstract boolean isList();
public abstract Text getColumnValue(int columnPos); protected abstract String getColumnValue(int columnPos);
public abstract String getListName(); protected abstract PDFTextAlignment getAlignment(int columnPos);
protected abstract Float getCellPadding (int columnPos);
protected abstract String getListName();
protected abstract String getVarName();
protected abstract void addColumn(TextElement element);
protected abstract void addColumn(TextElement element, Float padding);
public abstract String getVarName();
} }

View File

@ -0,0 +1,65 @@
package de.muehlencord.shared.pdf;
import com.google.gson.annotations.Expose;
/**
*
* @author joern.muehlencord
*/
public class TextCellValue extends CellValue {
@Expose
private final TextElement cellValue;
@Expose
private final Integer colSize;
@Expose
private final Float cellPadding;
public TextCellValue(String cellValue, int colSizes) {
this.cellValue = new TextElement(cellValue);
this.colSize = colSizes;
this.cellPadding = null;
}
public TextCellValue(String cellValue, int colSizes, float cellPadding) {
this.cellValue = new TextElement(cellValue);
this.colSize = colSizes;
this.cellPadding = cellPadding;
}
public TextCellValue(String cellValue, int colSizes, PDFTextAlignment align) {
this.cellValue = new TextElement(cellValue, align);
this.colSize = colSizes;
this.cellPadding = null;
}
public TextCellValue(String cellValue, int colSize, PDFTextAlignment align, float cellPadding) {
this.cellValue = new TextElement(cellValue, align);
this.colSize = colSize;
this.cellPadding = cellPadding;
}
/* *** getter / setter *** */
public String getCellText() {
return cellValue.getText();
}
public PDFTextAlignment getAlignment() {
return cellValue.getAlign();
}
@Override
public int getColSize() {
return colSize;
}
@Override
public float getCellPadding() {
if (cellPadding == null) {
return 0F;
} else {
return cellPadding;
}
}
}

View File

@ -6,40 +6,40 @@ import com.google.gson.annotations.Expose;
* *
* @author joern.muehlencord * @author joern.muehlencord
*/ */
public class Text extends PDFElement { class TextElement {
@Expose @Expose
private final String text; private final String text;
@Expose @Expose
private final String fontAlias; private final String fontAlias;
@Expose @Expose
private TextAlignment align; private final PDFTextAlignment align;
public Text() { public TextElement() {
this.text = ""; this.text = "";
this.fontAlias = null; this.fontAlias = null;
this.align = null; this.align = null;
} }
public Text(String text) { public TextElement(String text) {
this.text = text; this.text = text;
this.fontAlias = null; this.fontAlias = null;
this.align = null; this.align = null;
} }
public Text(String text, TextAlignment align) { public TextElement(String text, PDFTextAlignment align) {
this.text = text; this.text = text;
this.fontAlias = null; this.fontAlias = null;
this.align = align; this.align = align;
} }
public Text(String text, String fontAlias) { public TextElement(String text, String fontAlias) {
this.text = text; this.text = text;
this.fontAlias = fontAlias; this.fontAlias = fontAlias;
this.align = null; this.align = null;
} }
public Text(String text, String fontAlias, TextAlignment align) { public TextElement(String text, String fontAlias, PDFTextAlignment align) {
this.text = text; this.text = text;
this.fontAlias = fontAlias; this.fontAlias = fontAlias;
this.align = align; this.align = align;
@ -54,9 +54,9 @@ public class Text extends PDFElement {
return fontAlias; return fontAlias;
} }
public TextAlignment getAlign() { public PDFTextAlignment getAlign() {
if (align == null) { if (align == null) {
return TextAlignment.LEFT; return PDFTextAlignment.LEFT;
} else { } else {
return align; return align;
} }

View File

@ -0,0 +1,27 @@
package de.muehlencord.shared.pdf.util;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import javax.imageio.ImageIO;
/**
*
* @author joern.muehlencord
*/
public class ImageUtil {
public static String getEncodedString(BufferedImage img) throws IOException {
final ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageIO.write(img, "png", Base64.getEncoder().wrap(os));
return os.toString(StandardCharsets.UTF_8.name());
}
public static BufferedImage getImageFromEncodedString(String base64CodedString) throws IOException {
return ImageIO.read(new ByteArrayInputStream(Base64.getDecoder().decode(base64CodedString)));
}
}

View File

@ -1,6 +1,7 @@
package de.muehlencord.shared.pdf; package de.muehlencord.shared.pdf;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date;
import java.util.List; import java.util.List;
/** /**
@ -11,6 +12,11 @@ public class Invoice {
private final List<InvoiceLine> invoiceLines; private final List<InvoiceLine> invoiceLines;
private Date invoiceDate;
private String customerNumber;
private String invoiceNumber;
private String logo = null;
public Invoice() { public Invoice() {
this.invoiceLines = new ArrayList<>(); this.invoiceLines = new ArrayList<>();
} }
@ -19,7 +25,40 @@ public class Invoice {
this.invoiceLines.add(il); this.invoiceLines.add(il);
} }
/* *** getter / setter *** */
public List<InvoiceLine> getInvoiceLines() { public List<InvoiceLine> getInvoiceLines() {
return invoiceLines; return invoiceLines;
} }
public String getLogo() {
return logo;
}
public void setLogo(String logo) {
this.logo = logo;
}
public Date getInvoiceDate() {
return invoiceDate;
}
public void setInvoiceDate(Date invoiceDate) {
this.invoiceDate = invoiceDate;
}
public String getCustomerNumber() {
return customerNumber;
}
public void setCustomerNumber(String customerNumber) {
this.customerNumber = customerNumber;
}
public String getInvoiceNumber() {
return invoiceNumber;
}
public void setInvoiceNumber(String invoiceNumber) {
this.invoiceNumber = invoiceNumber;
}
} }

View File

@ -1,5 +1,6 @@
package de.muehlencord.shared.pdf; package de.muehlencord.shared.pdf;
import de.muehlencord.shared.pdf.util.ImageUtil;
import freemarker.template.Configuration; import freemarker.template.Configuration;
import freemarker.template.Template; import freemarker.template.Template;
import freemarker.template.TemplateExceptionHandler; import freemarker.template.TemplateExceptionHandler;
@ -26,70 +27,67 @@ public class PDFDocumentTest {
public void testToJson() throws FileNotFoundException, IOException, ConfigurationException, TemplateException { public void testToJson() throws FileNotFoundException, IOException, ConfigurationException, TemplateException {
System.out.println("testToJson"); System.out.println("testToJson");
PDFDocument doc = new PDFDocument(); PDFDocument doc = new PDFDocument();
doc.addFont("bold", new Font("Helvetica-Bold", 12, 2)); doc.addFont("bold", new PDFFont("Helvetica-Bold", 12, 2));
doc.addFont("helv12", new Font("Helvetica", 12, 2)); doc.addFont("helv12", new PDFFont("Helvetica", 12, 2));
doc.setPaperSize(PaperSize.A4); doc.setPaperSize(PDFPaperSize.A4);
TextContent addressContent = new TextContent(doc, 40F, 692F, "Max Mustermann") PDFTextContent addressContent = new PDFTextContent(doc, 40F, 692F, "Max Mustermann")
.addLine("Musterstraße 123") .addLine("Musterstraße 123")
.addLine("12345 Musterhausen"); .addLine("12345 Musterhausen");
doc.addContent(addressContent); doc.addContent(addressContent);
String fileName = "c:/temp/logo-verkehrsverein-hoevelh.jpg"; PDFImageContent logoContent = new PDFImageContent(doc, 400F, 700F, 0.6F, "${invoice.logo}");
BufferedImage image = ImageIO.read(new File(fileName));
ImageContent logoContent = new ImageContent(doc, 400F, 700F, 0.6F, image);
doc.addContent(logoContent); doc.addContent(logoContent);
PDFTextContent informationContent = new PDFTextContent(doc, 400F, 662F);
TextContent informationContent = new TextContent(doc, 400F, 662F);
informationContent.addLine("Anzeigenabrechnung", "bold"); informationContent.addLine("Anzeigenabrechnung", "bold");
informationContent.addLine("Veronika Mühlencord", "helv12"); informationContent.addLine("Veronika Mühlencord", "helv12");
informationContent.addLine("Telefon: 05257/940154", "helv12"); informationContent.addLine("Telefon: 05257/940154", "helv12");
informationContent.addLine("Telefax: 05257/940156", "helv12"); informationContent.addLine("Telefax: 05257/940156", "helv12");
informationContent.addLine(); informationContent.addLine();
informationContent.addLine("Hövelhof, den ${invoiceDate?date}", "bold"); informationContent.addLine("Hövelhof, den ${invoice.invoiceDate?date}", "bold");
doc.addContent(informationContent); doc.addContent(informationContent);
TableContent informationContent2 = new TableContent(doc, doc.getStandardFont()); PDFTableContent informationContent2 = new PDFTableContent(doc, doc.getStandardFont());
informationContent2.getHeaders() informationContent2.getHeaders()
.add("Kunden-Nr", 100) .add("Kunden-Nr", 100)
.add("${customerNumber}", 100); .add("${invoice.customerNumber}", 100);
informationContent2.addLine("Rechnungs-Nr.:", "${invoiceNumber}"); informationContent2.addRow("Rechnungs-Nr.:", "${invoice.invoiceNumber}")
informationContent2.addLine("Ausgabe: ", "Dezember"); .addRow("Ausgabe: ", "Dezember")
informationContent2.addLine("Rechnungsdatum:", "${invoiceDate?date}"); .addRow("Rechnungsdatum:", "${invoice.invoiceDate?date}");
doc.addContent(informationContent2); doc.addContent(informationContent2);
TextContent invoiceInfoInformation = new TextContent(doc, 40F, 442F, "Sehr geehrter Anzeigenkunde, ") PDFTextContent invoiceInfoInformation = new PDFTextContent(doc, 40F, 442F, "Sehr geehrter Anzeigenkunde, ")
.addLine() .addLine()
.addLine() .addLine()
.addLine("Wir danken für den Auftrag und bitten um Erledigung der folgenden Anzeigenabrechnung") .addLine("Wir danken für den Auftrag und bitten um Erledigung der folgenden Anzeigenabrechnung")
.addLine(); .addLine();
doc.addContent(invoiceInfoInformation); doc.addContent(invoiceInfoInformation);
TableContent invoiceLines = new TableContent(doc, doc.getFontByAlias("bold")); PDFTableContent invoiceLines = new PDFTableContent(doc, doc.getFontByAlias("bold"));
invoiceLines.getHeaders() invoiceLines.getHeaders()
.add("Menge", 50, 10F) .add("Menge", 50)
.add("Beschreibung", 300, 10F) .add("Beschreibung", 300)
.add(new Text("Einzelpreis", TextAlignment.RIGHT), 80) .add("Einzelpreis", 80, PDFTextAlignment.RIGHT)
.add(new Text("Summe", TextAlignment.RIGHT), 80); .add("Summe", 80, PDFTextAlignment.RIGHT);
invoiceLines.addTextLine( invoiceLines.addRow()
new Text("1000", TextAlignment.RIGHT), .addColumn("1000", PDFTextAlignment.RIGHT, 5F)
new Text("Anzeige Hövelhofer Rundschau"), .addColumn("Anzeige Hövelhofer Rundschau")
new Text("10,00 €", TextAlignment.RIGHT), .addColumn("10,00 €", PDFTextAlignment.RIGHT)
new Text("10,00 €", TextAlignment.RIGHT)); .addColumn("10,00 €", PDFTextAlignment.RIGHT);
invoiceLines.addTextLine( invoiceLines.addListRow("invoice.invoiceLines", "invoiceline")
new Text("${invoiceline.amount}", TextAlignment.RIGHT), .addColumn("${invoiceline.amount}", PDFTextAlignment.RIGHT, 5F )
new Text("${invoiceline.description}"), .addColumn("${invoiceline.description}")
new Text("${invoiceline.price}", TextAlignment.RIGHT), .addColumn("${invoiceline.price}", PDFTextAlignment.RIGHT)
new Text("${invoiceline.total}", TextAlignment.RIGHT)).createList("invoiceLines", "invoiceline"); .addColumn("${invoiceline.total}", PDFTextAlignment.RIGHT);
invoiceLines.addTextLine( invoiceLines.addRow()
new Text("2", TextAlignment.RIGHT), .addColumn("2", PDFTextAlignment.RIGHT, 5F)
new Text("Anzeige Hövelhofer Rundschau"), .addColumn("Anzeige Hövelhofer Rundschau")
new Text("10,00 €", TextAlignment.RIGHT), .addColumn("10,00 €", PDFTextAlignment.RIGHT)
new Text("20,00 €", TextAlignment.RIGHT)); .addColumn("20,00 €", PDFTextAlignment.RIGHT);
doc.addContent(invoiceLines); doc.addContent(invoiceLines);
TextContent test = new TextContent(doc) PDFTextContent test = new PDFTextContent(doc)
.addLine("Das ist ein Test"); .addLine("Das ist ein Test");
doc.addContent(test); doc.addContent(test);
@ -109,14 +107,18 @@ public class PDFDocumentTest {
PDFTemplate pdfDoc = new PDFTemplate(template); PDFTemplate pdfDoc = new PDFTemplate(template);
Invoice invoice = new Invoice(); Invoice invoice = new Invoice();
invoice.setInvoiceDate(new Date());
invoice.setCustomerNumber("8755");
invoice.setInvoiceNumber("1234567");
invoice.addInvoiceLine(new InvoiceLine("Product 1", "10,00 €", "1", "10,00 €")); invoice.addInvoiceLine(new InvoiceLine("Product 1", "10,00 €", "1", "10,00 €"));
invoice.addInvoiceLine(new InvoiceLine("Product 2", "5,00 €", "10", "50,00 €")); invoice.addInvoiceLine(new InvoiceLine("Product 2", "5,00 €", "10", "50,00 €"));
invoice.addInvoiceLine(new InvoiceLine("Product 3", "100,00 €", "20", "2000,00 €")); invoice.addInvoiceLine(new InvoiceLine("Product 3", "100,00 €", "20", "2000,00 €"));
pdfDoc.addToDatamodel("invoiceDate", new Date()); String fileName = "c:/temp/logo-verkehrsverein-hoevelh.jpg";
pdfDoc.addToDatamodel("customerNumber", "8755"); BufferedImage image = ImageIO.read(new File(fileName));
pdfDoc.addToDatamodel("invoiceNumber", "1234567"); invoice.setLogo(ImageUtil.getEncodedString(image));
pdfDoc.addToDatamodel("invoiceLines", invoice.getInvoiceLines());
pdfDoc.addToDatamodel("invoice", invoice);
pdfDoc.create("c:/temp/test.pdf"); pdfDoc.create("c:/temp/test.pdf");
} }

View File

@ -18,7 +18,7 @@ public class TextTest {
+ "\"text\": \"Rechnungs-Nr.:\"\n" + "\"text\": \"Rechnungs-Nr.:\"\n"
+ "}"; + "}";
Text text = GsonUtil.getGsonInstance().fromJson(jsonString, Text.class); TextElement text = GsonUtil.getGsonInstance().fromJson(jsonString, TextElement.class);
assertNotNull ("text object", text); assertNotNull ("text object", text);
assertEquals ("text value", "Rechnungs-Nr.:", text.getText()); assertEquals ("text value", "Rechnungs-Nr.:", text.getText());