added download from excel and zip in frontend

This commit is contained in:
verboomp
2026-02-23 16:19:57 +01:00
parent e0c6a7db5a
commit 746294d640
15 changed files with 221 additions and 90 deletions

View File

@@ -16,6 +16,7 @@ import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import marketing.heyday.hartmann.fotodocumentation.core.model.Questionnaire;
import marketing.heyday.hartmann.fotodocumentation.core.model.QuestionnaireCustomer;
import marketing.heyday.hartmann.fotodocumentation.core.utils.QuestionnaireJsonParser.MatrixAnswer;
import marketing.heyday.hartmann.fotodocumentation.core.utils.QuestionnaireJsonParser.QuestionJsonObj;
/**
@@ -33,7 +34,9 @@ public class ExcelUtils {
public Optional<byte[]> create(QuestionnaireCustomer customer, List<Questionnaire> questionnaires) {
LOG.debug("Create excel file for customer " + customer);
// TODO: implement excel export
if(customer == null || questionnaires.isEmpty()) {
return Optional.empty();
}
try (ByteArrayOutputStream bos = new ByteArrayOutputStream(); XSSFWorkbook workbook = new XSSFWorkbook()) {
@@ -176,12 +179,7 @@ public class ExcelUtils {
if (!answer.selected()) {
continue;
}
int index = 0;
for (int i = 0; i < answerOpts.size(); i++) {
if (answer.answer().equalsIgnoreCase(answerOpts.get(i).answer())) {
index = i;
}
}
int index = getMatrixAnswerIndex(answerOpts, answer);
var cell = questionRow.createCell(1 + index);
cell.setCellType(CellType.BOOLEAN);
cell.setCellValue(answer.selected());
@@ -190,4 +188,14 @@ public class ExcelUtils {
}
return count;
}
private int getMatrixAnswerIndex(List<MatrixAnswer> answerOpts, MatrixAnswer answer) {
int index = 0;
for (int i = 0; i < answerOpts.size(); i++) {
if (answer.answer().equalsIgnoreCase(answerOpts.get(i).answer())) {
index = i;
}
}
return index;
}
}

View File

@@ -29,17 +29,17 @@ import com.drew.metadata.exif.ExifIFD0Directory;
*/
public interface ImageHandler {
static final Log LOG = LogFactory.getLog(ImageHandler.class);
Log LOG = LogFactory.getLog(ImageHandler.class);
/**
* Reads image bytes and returns a BufferedImage with correct EXIF orientation applied.
*/
default BufferedImage readImageWithCorrectOrientation(byte[] imageBytes) throws IOException {
int orientation = getExifOrientation(imageBytes);
BufferedImage image = ImageIO.read(new ByteArrayInputStream(imageBytes));
if (image == null) {
throw new IOException("Failed to read image from byte array");
}
int orientation = getExifOrientation(imageBytes);
return applyOrientation(image, orientation);
}

View File

@@ -228,7 +228,9 @@ public class PdfUtils implements ImageHandler {
// 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(" ");
if (!remaining.isEmpty()) {
remaining.append(" ");
}
remaining.append(words[i]);
}
return remaining.toString();
@@ -289,7 +291,7 @@ public class PdfUtils implements ImageHandler {
cs.fill();
}
}
private void drawCircle(PDPageContentStream cs, float cx, float cy, float r) throws IOException {
float k = 0.5523f; // Bezier approximation for circle
cs.moveTo(cx - r, cy);

View File

@@ -12,6 +12,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import jakarta.json.*;
import jakarta.json.JsonValue.ValueType;
import jakarta.json.stream.JsonParsingException;
/**
@@ -74,10 +75,10 @@ public class QuestionnaireJsonParser {
public record QuestionJsonObj(String id, String title, int order, String type, String data) {
public List<MatrixQuestion> getMatrixAnswer() {
return getValue("questions", () -> null, (questions) -> {
return getValue("questions", () -> null, matrixQuestions -> {
var retVal = new ArrayList<MatrixQuestion>();
for (var question : questions) {
for (var question : matrixQuestions) {
var questionObj = question.asJsonObject();
var id = questionObj.getString("id");
var title = questionObj.getString("title");
@@ -101,11 +102,15 @@ public class QuestionnaireJsonParser {
}
public Integer getNumberAnswer() {
return getValue(() -> null, (answers) -> {
return getValue(() -> null, answers -> {
for (var answer : answers) {
var answerObj = answer.asJsonObject();
if (answerObj.getBoolean("selected")) {
return answerObj.getInt("answer");
var value = answerObj.get("answer");
if (value.getValueType() == ValueType.NUMBER) {
return answerObj.getInt("answer");
}
return Integer.parseInt(answerObj.getString("answer"));
}
}
return null;
@@ -113,7 +118,7 @@ public class QuestionnaireJsonParser {
}
public String getSingleAnswer() {
return getValue(() -> "", (answers) -> {
return getValue(() -> "", answers -> {
for (var answer : answers) {
var answerObj = answer.asJsonObject();
if (answerObj.getBoolean("selected")) {
@@ -125,7 +130,7 @@ public class QuestionnaireJsonParser {
}
public List<String> getMultiAnswer() {
return getValue(() -> List.of(), (answers) -> {
return getValue(() -> List.of(), answers -> {
List<String> retVal = new ArrayList<>();
for (var answer : answers) {
var answerObj = answer.asJsonObject();

View File

@@ -246,7 +246,7 @@ class ExcelUtilsTest implements TestAble {
private Questionnaire createQuestionnaire(Date date, String questions) {
return new Questionnaire.Builder()
.questionnaireDate(date)
.questions(QuestionnaireJsonParserTest.testJson1)
.questions(QuestionnaireJsonParserTest.TEST_JSON_1)
.build();
}
}

View File

@@ -21,14 +21,14 @@ public class QuestionnaireJsonParserTest {
@Test
public void testJson1() {
var parser = new QuestionnaireJsonParser();
boolean retVal = parser.parse(testJson1);
boolean retVal = parser.parse(TEST_JSON_1);
assertTrue(retVal);
var questions = parser.getQuestions();
assertEquals(10, questions.size());
}
public static final String testJson1 = """
public static final String TEST_JSON_1 = """
[
{
"id": "question1",