Tweaking padding in customer list and update look and feel pdf export
This commit is contained in:
@@ -70,7 +70,8 @@ public class PdfUtils {
|
||||
float pageWidth = page.getMediaBox().getWidth();
|
||||
float pageHeight = page.getMediaBox().getHeight();
|
||||
float contentWidth = pageWidth - 2 * PAGE_MARGIN;
|
||||
float halfWidth = contentWidth / 2F;
|
||||
float imageWidth = contentWidth * 0.75F;
|
||||
float metadataWidth = contentWidth * 0.25F;
|
||||
|
||||
try (PDPageContentStream cs = new PDPageContentStream(document, page)) {
|
||||
float yPosition = pageHeight - 50F;
|
||||
@@ -87,10 +88,10 @@ public class PdfUtils {
|
||||
firstPage = false;
|
||||
}
|
||||
|
||||
// Left side: image (50% of content width)
|
||||
// Left side: image (75% of content width)
|
||||
float imageX = PAGE_MARGIN;
|
||||
float imageY = yPosition;
|
||||
float imageMaxWidth = halfWidth - 10F;
|
||||
float imageMaxWidth = imageWidth - 10F;
|
||||
float imageMaxHeight = pageHeight - 2 * PAGE_MARGIN - 40F;
|
||||
|
||||
if (picture.getImage() != null) {
|
||||
@@ -108,30 +109,25 @@ public class PdfUtils {
|
||||
}
|
||||
}
|
||||
|
||||
// Right side: metadata (top-aligned with image)
|
||||
float rightX = PAGE_MARGIN + halfWidth + 10F;
|
||||
float rightY = imageY - 32F;
|
||||
// Right side: metadata (25% of content width, top-aligned with image)
|
||||
float rightX = PAGE_MARGIN + imageWidth + 10F;
|
||||
float rightY = imageY - 10F;
|
||||
|
||||
// Date (no label, bold, size 44)
|
||||
// Date (bold, size 10 - matching labels)
|
||||
String dateStr = picture.getPictureDate() != null ? (DATE_FORMAT.format(picture.getPictureDate()) + " UHR") : "";
|
||||
cs.setFont(fontBold, 32);
|
||||
cs.setFont(fontBold, 10);
|
||||
cs.setNonStrokingColor(COLOR_DATE);
|
||||
cs.beginText();
|
||||
cs.newLineAtOffset(rightX, rightY);
|
||||
cs.showText(dateStr);
|
||||
cs.endText();
|
||||
rightY -= 54F;
|
||||
rightY -= 24F;
|
||||
|
||||
// Customer number
|
||||
float kundenNummerY = rightY;
|
||||
rightY = drawLabel(cs, fontBold, "KUNDENNUMMER", rightX, rightY);
|
||||
rightY = drawValue(cs, fontRegular, nullSafe(customer.getCustomerNumber()), rightX, rightY);
|
||||
rightY -= 10F;
|
||||
|
||||
// Evaluation card with circles
|
||||
float circlesX = rightX + 140F;
|
||||
drawEvaluationCard(cs, fontBold, circlesX, kundenNummerY, picture.getEvaluation());
|
||||
|
||||
// ZIP
|
||||
rightY = drawLabel(cs, fontBold, "PLZ", rightX, rightY);
|
||||
rightY = drawValue(cs, fontRegular, nullSafe(customer.getZip()), rightX, rightY);
|
||||
@@ -142,9 +138,27 @@ public class PdfUtils {
|
||||
rightY = drawValue(cs, fontRegular, nullSafe(customer.getCity()), rightX, rightY);
|
||||
rightY -= 10F;
|
||||
|
||||
// Evaluation card with circles
|
||||
float evaluationY = rightY;
|
||||
drawEvaluationCard(cs, fontBold, rightX, evaluationY, picture.getEvaluation());
|
||||
rightY -= 80F;
|
||||
|
||||
// Comment
|
||||
rightY = drawLabel(cs, fontBold, "KOMMENTAR", rightX, rightY);
|
||||
drawWrappedText(cs, fontRegular, nullSafe(picture.getComment()), rightX, rightY, halfWidth - 20f);
|
||||
String remainingComment = drawWrappedText(cs, fontRegular, nullSafe(picture.getComment()), rightX, rightY, metadataWidth - 20f, 50F);
|
||||
|
||||
// Continue comment on additional pages if needed
|
||||
while (remainingComment != null && !remainingComment.isEmpty()) {
|
||||
PDPage continuationPage = new PDPage(new PDRectangle(PDRectangle.A4.getHeight(), PDRectangle.A4.getWidth()));
|
||||
document.addPage(continuationPage);
|
||||
|
||||
try (PDPageContentStream continuationCs = new PDPageContentStream(document, continuationPage)) {
|
||||
float continuationY = continuationPage.getMediaBox().getHeight() - PAGE_MARGIN;
|
||||
float continuationWidth = continuationPage.getMediaBox().getWidth() - 2 * PAGE_MARGIN;
|
||||
continuationY = drawLabel(continuationCs, fontBold, "KOMMENTAR (FORTSETZUNG)", PAGE_MARGIN, continuationY);
|
||||
remainingComment = drawWrappedText(continuationCs, fontRegular, remainingComment, PAGE_MARGIN, continuationY, continuationWidth, 50F);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,9 +203,9 @@ public class PdfUtils {
|
||||
return y - 14F;
|
||||
}
|
||||
|
||||
private void drawWrappedText(PDPageContentStream cs, PDFont font, String text, float x, float y, float maxWidth) throws IOException {
|
||||
private String drawWrappedText(PDPageContentStream cs, PDFont font, String text, float x, float y, float maxWidth, float minY) throws IOException {
|
||||
if (text == null || text.isEmpty()) {
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
cs.setFont(font, 10);
|
||||
cs.setNonStrokingColor(COLOR_TEXT_GRAY);
|
||||
@@ -199,11 +213,23 @@ public class PdfUtils {
|
||||
String[] words = text.split("\\s+");
|
||||
StringBuilder line = new StringBuilder();
|
||||
float currentY = y;
|
||||
int wordIndex = 0;
|
||||
|
||||
for (String word : words) {
|
||||
for (wordIndex = 0; wordIndex < words.length; wordIndex++) {
|
||||
String word = words[wordIndex];
|
||||
String testLine = line.isEmpty() ? word : (line + " " + word);
|
||||
float textWidth = font.getStringWidth(testLine) / 1000F * 10F;
|
||||
if (textWidth > maxWidth && !line.isEmpty()) {
|
||||
// Check if we have room for this line
|
||||
if (currentY < minY) {
|
||||
// Return remaining text starting from current word
|
||||
StringBuilder remaining = new StringBuilder(line);
|
||||
for (int i = wordIndex; i < words.length; i++) {
|
||||
if (!remaining.isEmpty()) remaining.append(" ");
|
||||
remaining.append(words[i]);
|
||||
}
|
||||
return remaining.toString();
|
||||
}
|
||||
cs.beginText();
|
||||
cs.newLineAtOffset(x, currentY);
|
||||
cs.showText(line.toString());
|
||||
@@ -215,45 +241,36 @@ public class PdfUtils {
|
||||
}
|
||||
}
|
||||
if (!line.isEmpty()) {
|
||||
if (currentY < minY) {
|
||||
return line.toString();
|
||||
}
|
||||
cs.beginText();
|
||||
cs.newLineAtOffset(x, currentY);
|
||||
cs.showText(line.toString());
|
||||
cs.endText();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void drawEvaluationCard(PDPageContentStream cs, PDFont fontBold, float x, float y, Integer evaluation) throws IOException {
|
||||
int eval = evaluation != null ? evaluation : 0;
|
||||
Color[] colors = { COLOR_GREEN, COLOR_YELLOW, COLOR_RED };
|
||||
|
||||
float cardPadding = 10F;
|
||||
float cardWidth = 2 * CIRCLE_SPACING + 2 * HIGHLIGHT_RADIUS + 2 * cardPadding;
|
||||
float labelHeight = 14F;
|
||||
float cardHeight = labelHeight + 2 * HIGHLIGHT_RADIUS + 2 * cardPadding + 4F;
|
||||
float cardX = x - HIGHLIGHT_RADIUS - cardPadding;
|
||||
float cardY = y - cardHeight + cardPadding;
|
||||
|
||||
// Draw card background (rounded rectangle)
|
||||
cs.setStrokingColor(new Color(0xDD, 0xDD, 0xDD));
|
||||
cs.setNonStrokingColor(new Color(0xF8, 0xF8, 0xF8));
|
||||
cs.setLineWidth(1f);
|
||||
drawRoundedRect(cs, cardX, cardY, cardWidth, cardHeight, 6F);
|
||||
cs.fillAndStroke();
|
||||
|
||||
// Draw "BEWERTUNG" label above circles
|
||||
float labelX = x;
|
||||
float labelY = y - labelHeight;
|
||||
cs.setFont(fontBold, 9);
|
||||
cs.setFont(fontBold, 10);
|
||||
cs.setNonStrokingColor(COLOR_CUSTOMER_NAME);
|
||||
cs.beginText();
|
||||
cs.newLineAtOffset(labelX, labelY);
|
||||
cs.newLineAtOffset(x, labelY);
|
||||
cs.showText("BEWERTUNG");
|
||||
cs.endText();
|
||||
|
||||
// Draw circles below the label
|
||||
float circleY = labelY - cardPadding - HIGHLIGHT_RADIUS - 2F;
|
||||
float circleY = labelY - HIGHLIGHT_RADIUS - 10F;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
float cx = x + i * CIRCLE_SPACING;
|
||||
float cx = x + CIRCLE_RADIUS + i * CIRCLE_SPACING;
|
||||
|
||||
// Highlight circle if this matches the evaluation (1=green, 2=yellow, 3=red)
|
||||
if (eval == i + 1) {
|
||||
|
||||
@@ -78,7 +78,7 @@ class PdfUtilsTest {
|
||||
byte[] pdfBytes = pdfUtils.createPdf(customer, pictures);
|
||||
|
||||
try (PDDocument document = Loader.loadPDF(pdfBytes)) {
|
||||
assertEquals(3, document.getNumberOfPages());
|
||||
assertEquals(4, document.getNumberOfPages());
|
||||
}
|
||||
writeToFile(pdfBytes, "createPdf_multiplePictures_createsOnPagePerPicture.pdf");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user