added first support for lists
This commit is contained in:
23
pdf/pom.xml
23
pdf/pom.xml
@ -19,7 +19,6 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
<version>4.12</version>
|
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
@ -45,27 +44,13 @@
|
|||||||
<artifactId>slf4j-log4j12</artifactId>
|
<artifactId>slf4j-log4j12</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>org.seleniumhq.selenium</groupId>
|
|
||||||
<artifactId>selenium-java</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
<version>2.44.0</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.opera</groupId>
|
|
||||||
<artifactId>operadriver</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
<version>1.5</version>
|
|
||||||
<exclusions>
|
|
||||||
<exclusion>
|
|
||||||
<groupId>org.seleniumhq.selenium</groupId>
|
|
||||||
<artifactId>selenium-remote-driver</artifactId>
|
|
||||||
</exclusion>
|
|
||||||
</exclusions>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>commons-io</groupId>
|
<groupId>commons-io</groupId>
|
||||||
<artifactId>commons-io</artifactId>
|
<artifactId>commons-io</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
@ -0,0 +1,71 @@
|
|||||||
|
package de.muehlencord.shared.pdf;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.Expose;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author joern.muehlencord
|
||||||
|
*/
|
||||||
|
public class DefaultTableRow extends TableRow {
|
||||||
|
|
||||||
|
@Expose
|
||||||
|
private final List<Text> row;
|
||||||
|
|
||||||
|
@Expose
|
||||||
|
private Boolean isList;
|
||||||
|
|
||||||
|
@Expose
|
||||||
|
private String listName;
|
||||||
|
|
||||||
|
@Expose
|
||||||
|
private String varName;
|
||||||
|
|
||||||
|
public DefaultTableRow() {
|
||||||
|
this.row = new ArrayList<>();
|
||||||
|
this.isList = false;
|
||||||
|
this.listName = null;
|
||||||
|
this.varName = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void add(Text text) {
|
||||||
|
row.add(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* *** TableRow methods *** */
|
||||||
|
@Override
|
||||||
|
public int getColumnCount() {
|
||||||
|
return row.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Text getColumnValue(int columnPos) {
|
||||||
|
return row.get(columnPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isList() {
|
||||||
|
return isList;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void createList(String listName, String varName) {
|
||||||
|
this.listName = listName;
|
||||||
|
this.varName = varName;
|
||||||
|
this.isList = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getListName() {
|
||||||
|
return listName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getVarName() {
|
||||||
|
return varName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -9,11 +9,12 @@ import com.google.gson.GsonBuilder;
|
|||||||
*/
|
*/
|
||||||
public class GsonUtil {
|
public class GsonUtil {
|
||||||
|
|
||||||
public final static Gson getGsonInstance() {
|
protected final static Gson getGsonInstance() {
|
||||||
return new GsonBuilder()
|
return new GsonBuilder()
|
||||||
.setPrettyPrinting()
|
.setPrettyPrinting()
|
||||||
.excludeFieldsWithoutExposeAnnotation()
|
.excludeFieldsWithoutExposeAnnotation()
|
||||||
.registerTypeAdapter(Content.class, new InterfaceAdapter<>())
|
.registerTypeAdapter(Content.class, new InterfaceAdapter<>())
|
||||||
|
.registerTypeAdapter(TableRow.class, new InterfaceAdapter<>())
|
||||||
.create();
|
.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,17 @@
|
|||||||
|
package de.muehlencord.shared.pdf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author joern.muehlencord
|
||||||
|
*/
|
||||||
|
public interface ListTemplate {
|
||||||
|
|
||||||
|
public void createList (String listName, String varName);
|
||||||
|
|
||||||
|
public boolean isList();
|
||||||
|
|
||||||
|
public String getListName();
|
||||||
|
|
||||||
|
public String getVarName();
|
||||||
|
|
||||||
|
}
|
||||||
@ -5,6 +5,8 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.ConcurrentLinkedDeque;
|
||||||
|
import org.apache.commons.lang3.text.StrBuilder;
|
||||||
import org.apache.pdfbox.pdmodel.font.PDFont;
|
import org.apache.pdfbox.pdmodel.font.PDFont;
|
||||||
import org.apache.pdfbox.pdmodel.font.PDType1Font;
|
import org.apache.pdfbox.pdmodel.font.PDType1Font;
|
||||||
|
|
||||||
@ -32,33 +34,110 @@ public class PDFDocument {
|
|||||||
this.fontMap = null;
|
this.fontMap = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String toJson() {
|
||||||
|
return GsonUtil.getGsonInstance().toJson(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String fromJson() {
|
||||||
|
return GsonUtil.getGsonInstance().toJson(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTemplateString() throws TemplateException {
|
||||||
|
|
||||||
|
ConcurrentLinkedDeque<Integer> bracketStack = new ConcurrentLinkedDeque<>();
|
||||||
|
int currentPosInTemplate = 0;
|
||||||
|
int currentStartOfSubelement = 0;
|
||||||
|
String templateString = GsonUtil.getGsonInstance().toJson(this);
|
||||||
|
String typeSearchString = " \"type\": \"de.muehlencord.shared.pdf.DefaultTableRow\"";
|
||||||
|
while (templateString.indexOf(typeSearchString, currentPosInTemplate) > 0) {
|
||||||
|
// get next element
|
||||||
|
currentPosInTemplate = templateString.indexOf(typeSearchString, currentPosInTemplate);
|
||||||
|
int posOpenBracket = templateString.substring(currentStartOfSubelement, currentPosInTemplate).lastIndexOf("{") + currentStartOfSubelement;
|
||||||
|
int posCloseBracket;
|
||||||
|
// store position of 1st open bracket
|
||||||
|
bracketStack.push(posOpenBracket);
|
||||||
|
|
||||||
|
// work until closing bracket for this element
|
||||||
|
while ((!bracketStack.isEmpty()) && (currentPosInTemplate < templateString.length())) {
|
||||||
|
currentPosInTemplate += 1;
|
||||||
|
char currentChar = templateString.charAt(currentPosInTemplate);
|
||||||
|
if (currentChar == '{') {
|
||||||
|
// new open bracket found
|
||||||
|
posOpenBracket = currentPosInTemplate;
|
||||||
|
bracketStack.push(posOpenBracket);
|
||||||
|
} else if (currentChar == '}') {
|
||||||
|
if (bracketStack.isEmpty()) {
|
||||||
|
throw new TemplateException("Found closing bracket, but missing open bracket");
|
||||||
|
}
|
||||||
|
// new open bracket found
|
||||||
|
posCloseBracket = currentPosInTemplate;
|
||||||
|
posOpenBracket = bracketStack.pop();
|
||||||
|
if (bracketStack.isEmpty()) {
|
||||||
|
// next element starts behing the closing bracket earliests
|
||||||
|
currentStartOfSubelement = posCloseBracket + 1;
|
||||||
|
|
||||||
|
String jsonSubString = templateString.substring(posOpenBracket, posCloseBracket + 1);
|
||||||
|
System.out.println(jsonSubString);
|
||||||
|
|
||||||
|
// insert the list values into the gson string
|
||||||
|
TableRow element = GsonUtil.getGsonInstance().fromJson(jsonSubString, TableRow.class);
|
||||||
|
if (element.isList()) {
|
||||||
|
String listStartString = "<#list ";
|
||||||
|
listStartString += element.getListName();
|
||||||
|
listStartString += " as ";
|
||||||
|
listStartString += element.getVarName();
|
||||||
|
listStartString += ">\n";
|
||||||
|
|
||||||
|
String listEndString = "<#if ("+element.getVarName()+"?has_next)>,</#if>";
|
||||||
|
listEndString += "</#list>\n";
|
||||||
|
|
||||||
|
String newString = templateString.substring(0, posOpenBracket);
|
||||||
|
newString += listStartString;
|
||||||
|
newString += templateString.substring(posOpenBracket, posCloseBracket+1);
|
||||||
|
newString += listEndString;
|
||||||
|
newString += templateString.substring(posCloseBracket+1, templateString.length());
|
||||||
|
|
||||||
|
templateString = newString;
|
||||||
|
currentPosInTemplate += listStartString.length();
|
||||||
|
currentPosInTemplate += listEndString.length();
|
||||||
|
System.out.println(templateString.substring(posOpenBracket-10, posCloseBracket + listStartString.length() + listEndString.length()+10));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!bracketStack.isEmpty()) {
|
||||||
|
throw new TemplateException("Exception - stack not empty but end of string reached");
|
||||||
|
}
|
||||||
|
} // for all types
|
||||||
|
|
||||||
|
return templateString;
|
||||||
|
}
|
||||||
|
|
||||||
public void addFont(String name, Font font) {
|
public void addFont(String name, Font font) {
|
||||||
if (fontMap == null) {
|
if (fontMap == null) {
|
||||||
fontMap = new ConcurrentHashMap<>();
|
fontMap = new ConcurrentHashMap<>();
|
||||||
}
|
}
|
||||||
fontMap.put(name, font);
|
fontMap.put(name, font);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected PDFont getFont(String fontName) throws ConfigurationException {
|
protected PDFont getFont(String fontName) throws ConfigurationException {
|
||||||
if (fontName.equals(PDType1Font.HELVETICA.getBaseFont())) {
|
if (fontName.equals(PDType1Font.HELVETICA.getBaseFont())) {
|
||||||
return PDType1Font.HELVETICA;
|
return PDType1Font.HELVETICA;
|
||||||
} else if (fontName.equals(PDType1Font.HELVETICA_BOLD.getBaseFont())) {
|
} else if (fontName.equals(PDType1Font.HELVETICA_BOLD.getBaseFont())) {
|
||||||
return PDType1Font.HELVETICA_BOLD;
|
return PDType1Font.HELVETICA_BOLD;
|
||||||
}else {
|
} else {
|
||||||
throw new ConfigurationException("Font " + fontName + " not supported");
|
throw new ConfigurationException("Font " + fontName + " not supported");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Font getFontByAlias(String fontAlias) throws ConfigurationException {
|
public Font 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 {
|
||||||
throw new ConfigurationException("Font " + fontAlias + " not found in mapping. ");
|
throw new ConfigurationException("Font " + fontAlias + " not found in mapping. ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public PDFDocument addContent(Content content) {
|
public PDFDocument addContent(Content content) {
|
||||||
contentList.add(content);
|
contentList.add(content);
|
||||||
return this;
|
return this;
|
||||||
|
|||||||
@ -0,0 +1,9 @@
|
|||||||
|
package de.muehlencord.shared.pdf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author joern.muehlencord
|
||||||
|
*/
|
||||||
|
public class PDFElement {
|
||||||
|
|
||||||
|
}
|
||||||
@ -3,10 +3,12 @@ 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;
|
||||||
@ -32,9 +34,9 @@ public class PDFTemplate {
|
|||||||
this.template = template;
|
this.template = template;
|
||||||
this.dataModel = new ConcurrentHashMap<>();
|
this.dataModel = new ConcurrentHashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addToDatamodel (String key, Object value) {
|
public void addToDatamodel(String key, Object value) {
|
||||||
this.dataModel.put (key, value);
|
this.dataModel.put(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void create(String filenName) throws ConfigurationException, IOException {
|
public void create(String filenName) throws ConfigurationException, IOException {
|
||||||
@ -45,8 +47,8 @@ public class PDFTemplate {
|
|||||||
throw new IOException("Error while processing template", ex);
|
throw new IOException("Error while processing template", ex);
|
||||||
}
|
}
|
||||||
String json = out.toString();
|
String json = out.toString();
|
||||||
LOGGER.info(json);
|
LOGGER.debug(json);
|
||||||
|
|
||||||
Gson gson = GsonUtil.getGsonInstance();
|
Gson gson = GsonUtil.getGsonInstance();
|
||||||
PDFDocument pdfDoc = gson.fromJson(json, PDFDocument.class);
|
PDFDocument pdfDoc = gson.fromJson(json, PDFDocument.class);
|
||||||
|
|
||||||
@ -60,16 +62,16 @@ public class PDFTemplate {
|
|||||||
default:
|
default:
|
||||||
throw new ConfigurationException("Papersize " + pdfDoc.getPaperSize().getLabel() + " not supported");
|
throw new ConfigurationException("Papersize " + pdfDoc.getPaperSize().getLabel() + " not supported");
|
||||||
}
|
}
|
||||||
doc.addPage(page);
|
doc.addPage(page);
|
||||||
|
|
||||||
PDRectangle rect = page.getMediaBox();
|
PDRectangle rect = page.getMediaBox();
|
||||||
PDPageContentStream cos = new PDPageContentStream(doc, page, AppendMode.APPEND, false);
|
PDPageContentStream cos = new PDPageContentStream(doc, page, AppendMode.APPEND, false);
|
||||||
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.setCoordinate (coord);
|
content.setCoordinate(coord);
|
||||||
coord = content.addContentToPdf(rect, cos);
|
coord = content.addContentToPdf(rect, cos);
|
||||||
}
|
}
|
||||||
cos.close();
|
cos.close();
|
||||||
doc.save(filenName);
|
doc.save(filenName);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,17 +19,17 @@ public class TableContent extends Content {
|
|||||||
private final Font headerFont;
|
private final Font headerFont;
|
||||||
|
|
||||||
@Expose
|
@Expose
|
||||||
private TableHeader header;
|
private final TableHeader header;
|
||||||
|
|
||||||
@Expose
|
@Expose
|
||||||
private List<List<Text>> data = null;
|
private List<TableRow> data = null;
|
||||||
|
|
||||||
public TableContent (PDFDocument doc, Font hf) {
|
public TableContent(PDFDocument doc, Font 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 ArrayList<>();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public TableContent(PDFDocument doc, Font hf, int x, int y) {
|
public TableContent(PDFDocument doc, Font hf, int x, int y) {
|
||||||
@ -38,56 +38,66 @@ public class TableContent extends Content {
|
|||||||
this.headerFont = hf;
|
this.headerFont = hf;
|
||||||
this.data = new ArrayList<>();
|
this.data = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addLine(String... values) {
|
public DefaultTableRow addLine(String... values) {
|
||||||
addLine(Arrays.asList(values));
|
return addLine(Arrays.asList(values));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addLine(List<String> values) {
|
public DefaultTableRow addLine(List<String> values) {
|
||||||
List<Text> newLine = new ArrayList<>();
|
DefaultTableRow newLine = new DefaultTableRow();
|
||||||
values.stream().forEach((cellText) -> {
|
values.stream().forEach((cellText) -> {
|
||||||
newLine.add(new Text(cellText));
|
newLine.add(new Text(cellText));
|
||||||
});
|
});
|
||||||
data.add(newLine);
|
data.add(newLine);
|
||||||
|
return newLine;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected TableRow getRow (int no) {
|
||||||
|
return data.get(no);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int getRowCount() {
|
||||||
|
return data.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Coordinate addContentToPdf(PDRectangle rect, PDPageContentStream cos) throws IOException, ConfigurationException {
|
protected Coordinate addContentToPdf(PDRectangle rect, PDPageContentStream cos) throws IOException, ConfigurationException {
|
||||||
cos.beginText();
|
cos.beginText();
|
||||||
|
|
||||||
PDFont hFont = document.getFont(headerFont.getFontName());
|
PDFont hFont = document.getFont(headerFont.getFontName());
|
||||||
PDFont standardFont = document.getFont(document.getStandardFont().getFontName());
|
PDFont standardFont = document.getFont(document.getStandardFont().getFontName());
|
||||||
int xOffSet = 0;
|
int xOffSet = 0;
|
||||||
for (int i = 0; i < getHeaders().size(); i++) {
|
for (int i = 0; i < getHeaders().size(); i++) {
|
||||||
xOffSet -= header.getColumnSize(i);
|
xOffSet -= header.getColumnSize(i);
|
||||||
}
|
}
|
||||||
int yOffset = document.getStandardFont().getFontSize() * -1 - document.getStandardFont().getPadding();
|
int yOffset = document.getStandardFont().getFontSize() * -1 - document.getStandardFont().getPadding();
|
||||||
int currentX = x;
|
int currentX = x;
|
||||||
int currentY = y;
|
int currentY = y;
|
||||||
|
|
||||||
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++) {
|
||||||
cos.showText(header.getHeader(i).getText());
|
cos.showText(header.getHeader(i).getText());
|
||||||
cos.newLineAtOffset(header.getColumnSize(i), 0);
|
cos.newLineAtOffset(header.getColumnSize(i), 0);
|
||||||
}
|
}
|
||||||
if (data.size() == 0) {
|
if (data.isEmpty()) {
|
||||||
currentY -= headerFont.getFontSize() - headerFont.getPadding();
|
currentY -= headerFont.getFontSize() - headerFont.getPadding();
|
||||||
}
|
}
|
||||||
|
|
||||||
cos.setFont(standardFont, document.getStandardFont().getFontSize());
|
cos.setFont(standardFont, document.getStandardFont().getFontSize());
|
||||||
for (int lineNo = 0; lineNo < data.size(); lineNo++) {
|
for (int lineNo = 0; lineNo < data.size(); lineNo++) {
|
||||||
List<Text> currentRow = data.get(lineNo);
|
TableRow currentRow = data.get(lineNo);
|
||||||
cos.newLineAtOffset(xOffSet, yOffset);
|
cos.newLineAtOffset(xOffSet, yOffset);
|
||||||
currentY += yOffset;
|
currentY += yOffset;
|
||||||
for (int colNo = 0; colNo < currentRow.size(); colNo++) {
|
for (int colNo = 0; colNo < currentRow.getColumnCount(); colNo++) {
|
||||||
cos.showText(currentRow.get(colNo).getText());
|
cos.showText(currentRow.getColumnValue(colNo).getText());
|
||||||
cos.newLineAtOffset(header.getColumnSize(colNo), 0);
|
cos.newLineAtOffset(header.getColumnSize(colNo), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cos.endText();
|
currentY += yOffset;
|
||||||
|
cos.endText();
|
||||||
return new Coordinate(currentX, currentY);
|
|
||||||
|
return new Coordinate(currentX, currentY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* *** getter / setter *** */
|
/* *** getter / setter *** */
|
||||||
@ -97,5 +107,5 @@ public class TableContent extends Content {
|
|||||||
|
|
||||||
public TableHeader getHeaders() {
|
public TableHeader getHeaders() {
|
||||||
return header;
|
return header;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
21
pdf/src/main/java/de/muehlencord/shared/pdf/TableRow.java
Normal file
21
pdf/src/main/java/de/muehlencord/shared/pdf/TableRow.java
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package de.muehlencord.shared.pdf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author joern.muehlencord
|
||||||
|
*/
|
||||||
|
public abstract class TableRow {
|
||||||
|
|
||||||
|
public abstract int getColumnCount();
|
||||||
|
|
||||||
|
public abstract void createList(String listName, String varName);
|
||||||
|
|
||||||
|
public abstract boolean isList();
|
||||||
|
|
||||||
|
public abstract Text getColumnValue(int columnPos);
|
||||||
|
|
||||||
|
public abstract String getListName();
|
||||||
|
|
||||||
|
public abstract String getVarName();
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
package de.muehlencord.shared.pdf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author joern.muehlencord
|
||||||
|
*/
|
||||||
|
public class TemplateException extends Exception {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance of <code>TemplateException</code> without detail
|
||||||
|
* message.
|
||||||
|
*/
|
||||||
|
public TemplateException() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an instance of <code>TemplateException</code> with the
|
||||||
|
* specified detail message.
|
||||||
|
*
|
||||||
|
* @param msg the detail message.
|
||||||
|
*/
|
||||||
|
public TemplateException(String msg) {
|
||||||
|
super(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -6,7 +6,7 @@ import com.google.gson.annotations.Expose;
|
|||||||
*
|
*
|
||||||
* @author joern.muehlencord
|
* @author joern.muehlencord
|
||||||
*/
|
*/
|
||||||
public class Text {
|
public class Text extends PDFElement {
|
||||||
|
|
||||||
@Expose
|
@Expose
|
||||||
private final String text;
|
private final String text;
|
||||||
|
|||||||
@ -0,0 +1,35 @@
|
|||||||
|
package de.muehlencord.shared.pdf;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author joern.muehlencord
|
||||||
|
*/
|
||||||
|
public class DefaultTableRowTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFromJson() {
|
||||||
|
String jsonString = "{\n" +
|
||||||
|
" \"type\": \"de.muehlencord.shared.pdf.DefaultTableRow\",\n" +
|
||||||
|
" \"data\": {\n" +
|
||||||
|
" \"row\": [\n" +
|
||||||
|
" {\n" +
|
||||||
|
" \"text\": \"Rechnungs-Nr.:\"\n" +
|
||||||
|
" },\n" +
|
||||||
|
" {\n" +
|
||||||
|
" \"text\": \"${invoiceNumber}\"\n" +
|
||||||
|
" }\n" +
|
||||||
|
" ],\n" +
|
||||||
|
" \"isList\": false\n" +
|
||||||
|
" }\n" +
|
||||||
|
" }";
|
||||||
|
|
||||||
|
|
||||||
|
TableRow tableRow = GsonUtil.getGsonInstance().fromJson(jsonString, TableRow.class);
|
||||||
|
assertNotNull ("tableRowObject", tableRow);
|
||||||
|
assertEquals ("column count", 2, tableRow.getColumnCount());
|
||||||
|
assertFalse ("isList", tableRow.isList());
|
||||||
|
}
|
||||||
|
}
|
||||||
25
pdf/src/test/java/de/muehlencord/shared/pdf/Invoice.java
Normal file
25
pdf/src/test/java/de/muehlencord/shared/pdf/Invoice.java
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package de.muehlencord.shared.pdf;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author joern.muehlencord
|
||||||
|
*/
|
||||||
|
public class Invoice {
|
||||||
|
|
||||||
|
private final List<InvoiceLine> invoiceLines;
|
||||||
|
|
||||||
|
public Invoice() {
|
||||||
|
this.invoiceLines = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addInvoiceLine(InvoiceLine il) {
|
||||||
|
this.invoiceLines.add(il);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<InvoiceLine> getInvoiceLines() {
|
||||||
|
return invoiceLines;
|
||||||
|
}
|
||||||
|
}
|
||||||
58
pdf/src/test/java/de/muehlencord/shared/pdf/InvoiceLine.java
Normal file
58
pdf/src/test/java/de/muehlencord/shared/pdf/InvoiceLine.java
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
package de.muehlencord.shared.pdf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author joern.muehlencord
|
||||||
|
*/
|
||||||
|
public class InvoiceLine {
|
||||||
|
|
||||||
|
private String description;
|
||||||
|
private String price;
|
||||||
|
private String amount;
|
||||||
|
private String total;
|
||||||
|
|
||||||
|
public InvoiceLine(String description, String price, String amount, String total) {
|
||||||
|
this.description = description;
|
||||||
|
this.price = price;
|
||||||
|
this.amount = amount;
|
||||||
|
this.total = total;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDescription(String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPrice() {
|
||||||
|
return price;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPrice(String price) {
|
||||||
|
this.price = price;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAmount() {
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAmount(String amount) {
|
||||||
|
this.amount = amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTotal() {
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTotal(String total) {
|
||||||
|
this.total = total;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,17 +1,13 @@
|
|||||||
package de.muehlencord.shared.pdf;
|
package de.muehlencord.shared.pdf;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
|
||||||
import freemarker.template.Configuration;
|
import freemarker.template.Configuration;
|
||||||
import freemarker.template.Template;
|
import freemarker.template.Template;
|
||||||
import freemarker.template.TemplateExceptionHandler;
|
import freemarker.template.TemplateExceptionHandler;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
|
||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.junit.BeforeClass;
|
|
||||||
import org.junit.FixMethodOrder;
|
import org.junit.FixMethodOrder;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
@ -21,18 +17,11 @@ import org.junit.Test;
|
|||||||
*/
|
*/
|
||||||
@FixMethodOrder
|
@FixMethodOrder
|
||||||
public class PDFDocumentTest {
|
public class PDFDocumentTest {
|
||||||
|
|
||||||
private static Gson gson;
|
|
||||||
|
|
||||||
private String jsonString = null;
|
private String jsonString = null;
|
||||||
|
|
||||||
@BeforeClass
|
|
||||||
public static void setUpClass() {
|
|
||||||
gson = GsonUtil.getGsonInstance();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testToJson() throws FileNotFoundException, IOException, ConfigurationException {
|
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 Font("Helvetica-Bold", 12, 2));
|
||||||
@ -72,19 +61,20 @@ public class PDFDocumentTest {
|
|||||||
TableContent invoiceLines = new TableContent(doc, doc.getFontByAlias("bold"));
|
TableContent invoiceLines = new TableContent(doc, doc.getFontByAlias("bold"));
|
||||||
invoiceLines.getHeaders()
|
invoiceLines.getHeaders()
|
||||||
.add ("Menge", 100)
|
.add ("Menge", 100)
|
||||||
.add ("Beschreibung", 100)
|
.add ("Beschreibung", 300)
|
||||||
.add ("Einzelpreis", 100)
|
.add ("Einzelpreis", 100)
|
||||||
.add ("Summe", 100);
|
.add ("Summe", 100);
|
||||||
doc.addContent(invoiceLines);
|
invoiceLines.addLine("1","Anzeige Hövelhofer Rundschau", "10", "10");
|
||||||
|
invoiceLines.addLine ("${invoiceline.amount}", "${invoiceline.description}", "${invoiceline.price}", "${invoiceline.total}").createList("invoiceLines", "invoiceline");
|
||||||
|
invoiceLines.addLine("2","Anzeige Hövelhofer Rundschau", "10", "20");
|
||||||
|
doc.addContent(invoiceLines);
|
||||||
|
|
||||||
TextContent test = new TextContent (doc)
|
TextContent test = new TextContent (doc)
|
||||||
.addLine("Das ist ein Test");
|
.addLine("Das ist ein Test");
|
||||||
doc.addContent (test);
|
doc.addContent (test);
|
||||||
|
|
||||||
|
jsonString = doc.getTemplateString();
|
||||||
jsonString = gson.toJson(doc);
|
|
||||||
System.out.println(jsonString);
|
|
||||||
|
|
||||||
File file = new File("c:/temp/test.ftlh");
|
File file = new File("c:/temp/test.ftlh");
|
||||||
FileUtils.writeStringToFile(file, jsonString, "UTF-8");
|
FileUtils.writeStringToFile(file, jsonString, "UTF-8");
|
||||||
|
|
||||||
@ -97,9 +87,16 @@ public class PDFDocumentTest {
|
|||||||
|
|
||||||
Template template = cfg.getTemplate("test.ftlh");
|
Template template = cfg.getTemplate("test.ftlh");
|
||||||
PDFTemplate pdfDoc = new PDFTemplate(template);
|
PDFTemplate pdfDoc = new PDFTemplate(template);
|
||||||
|
|
||||||
|
Invoice invoice = new Invoice();
|
||||||
|
invoice.addInvoiceLine(new InvoiceLine ("Product 1", "10", "1", "10"));
|
||||||
|
invoice.addInvoiceLine(new InvoiceLine ("Product 2", "5", "10", "50"));
|
||||||
|
invoice.addInvoiceLine(new InvoiceLine ("Product 3", "100", "20", "2000"));
|
||||||
|
|
||||||
pdfDoc.addToDatamodel("invoiceDate", new Date());
|
pdfDoc.addToDatamodel("invoiceDate", new Date());
|
||||||
pdfDoc.addToDatamodel("customerNumber", "8755");
|
pdfDoc.addToDatamodel("customerNumber", "8755");
|
||||||
pdfDoc.addToDatamodel("invoiceNumber", "1234567");
|
pdfDoc.addToDatamodel("invoiceNumber", "1234567");
|
||||||
|
pdfDoc.addToDatamodel("invoiceLines", invoice.getInvoiceLines());
|
||||||
pdfDoc.create("c:/temp/test.pdf");
|
pdfDoc.create("c:/temp/test.pdf");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
27
pdf/src/test/java/de/muehlencord/shared/pdf/TextTest.java
Normal file
27
pdf/src/test/java/de/muehlencord/shared/pdf/TextTest.java
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package de.muehlencord.shared.pdf;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author joern.muehlencord
|
||||||
|
*/
|
||||||
|
public class TextTest {
|
||||||
|
|
||||||
|
public TextTest() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFromJson() {
|
||||||
|
String jsonString = "{\n"
|
||||||
|
+ "\"text\": \"Rechnungs-Nr.:\"\n"
|
||||||
|
+ "}";
|
||||||
|
|
||||||
|
Text text = GsonUtil.getGsonInstance().fromJson(jsonString, Text.class);
|
||||||
|
assertNotNull ("text object", text);
|
||||||
|
assertEquals ("text value", "Rechnungs-Nr.:", text.getText());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -12,6 +12,10 @@
|
|||||||
<logger name="org.hibernate">
|
<logger name="org.hibernate">
|
||||||
<level value="warn" />
|
<level value="warn" />
|
||||||
</logger>
|
</logger>
|
||||||
|
|
||||||
|
<logger name="org.gson">
|
||||||
|
<level value="DEBUG" />
|
||||||
|
</logger>
|
||||||
|
|
||||||
<category name="de.muehlencord">
|
<category name="de.muehlencord">
|
||||||
<priority value="DEBUG"/>
|
<priority value="DEBUG"/>
|
||||||
@ -26,7 +30,7 @@
|
|||||||
</category>
|
</category>
|
||||||
|
|
||||||
<root>
|
<root>
|
||||||
<level value="INFO" />
|
<level value="DEBUG" />
|
||||||
<appender-ref ref="consoleAppender" />
|
<appender-ref ref="consoleAppender" />
|
||||||
</root>
|
</root>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user