Pull request #94: RED-2414 rrs2
Merge in RED/redaction-report-service from RED-2414-rrs2 to master * commit '599a099d357b15ae05f8557af9f72713dea27fbd': RED-2414 Wrong scaling for Images in Reports RED-2414 Wrong scaling for Images in Reports - not fixed excel part
This commit is contained in:
commit
6980e1e342
@ -1,5 +1,48 @@
|
||||
package com.iqser.red.service.redaction.report.v1.server.service;
|
||||
|
||||
import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.DOSSIER_NAME_PLACEHOLDER;
|
||||
import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.EXCERPT_PLACEHOLDER;
|
||||
import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.FILE_NAME_PLACEHOLDER;
|
||||
import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.FORMAT_DATE_ENG;
|
||||
import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.FORMAT_DATE_ENG_PLACEHOLDER;
|
||||
import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.FORMAT_DATE_GER;
|
||||
import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.FORMAT_DATE_GER_PLACEHOLDER;
|
||||
import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.FORMAT_DATE_ISO;
|
||||
import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.FORMAT_DATE_ISO_PLACEHOLDER;
|
||||
import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.FORMAT_TIME_ISO;
|
||||
import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.FORMAT_TIME_ISO_PLACEHOLDER;
|
||||
import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.JUSTIFICATION_PARAGRAPH_PLACEHOLDER;
|
||||
import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.JUSTIFICATION_PLACEHOLDER;
|
||||
import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.JUSTIFICATION_REASON_PLACEHOLDER;
|
||||
import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.PAGE_PLACEHOLDER;
|
||||
import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.PARAGRAPH_PLACEHOLDER;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import org.apache.poi.ss.usermodel.Cell;
|
||||
import org.apache.poi.ss.usermodel.ClientAnchor;
|
||||
import org.apache.poi.ss.usermodel.CreationHelper;
|
||||
import org.apache.poi.ss.usermodel.Drawing;
|
||||
import org.apache.poi.ss.usermodel.Picture;
|
||||
import org.apache.poi.ss.usermodel.Row;
|
||||
import org.apache.poi.ss.usermodel.Sheet;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.DossierAttributeConfig;
|
||||
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.Dossier;
|
||||
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.DossierAttribute;
|
||||
@ -10,22 +53,10 @@ import com.iqser.red.service.redaction.report.v1.server.client.DossierAttributes
|
||||
import com.iqser.red.service.redaction.report.v1.server.client.FileAttributesConfigClient;
|
||||
import com.iqser.red.service.redaction.report.v1.server.model.ImagePlaceholder;
|
||||
import com.iqser.red.service.redaction.report.v1.server.model.ReportRedactionEntry;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.poi.ss.usermodel.*;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.*;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@ -232,30 +263,30 @@ public class ExcelTemplateReportGenerationService {
|
||||
for (Cell cell : row) {
|
||||
if (cell.getStringCellValue().contains(imagePlaceholder.getPlaceholder())) {
|
||||
try (ByteArrayInputStream is = new ByteArrayInputStream(imagePlaceholder.getImage())) {
|
||||
|
||||
// ByteArrayInputStream scaledImage = getScaledImage(is, PixelUtil.widthUnits2Pixel((short) sheet.getColumnWidth(cell.getColumnIndex())), PixelUtil.heightUnits2Pixel(cell.getRow().getHeight()));
|
||||
// is.reset();
|
||||
|
||||
double factor = calculateScale(is, PixelUtil.widthUnits2Pixel((short) sheet.getColumnWidth(cell.getColumnIndex())), PixelUtil.heightUnits2Pixel(cell.getRow().getHeight()));
|
||||
is.reset();
|
||||
|
||||
int pictureIdx = workbook.addPicture(is, XSSFWorkbook.PICTURE_TYPE_JPEG);
|
||||
is.reset();
|
||||
|
||||
//Returns an object that handles instantiating concrete classes
|
||||
CreationHelper helper = workbook.getCreationHelper();
|
||||
//Creates the top-level drawing patriarch.
|
||||
Drawing drawing = sheet.createDrawingPatriarch();
|
||||
//Create an anchor that is attached to the worksheet
|
||||
ClientAnchor anchor = helper.createClientAnchor();
|
||||
anchor.setAnchorType(ClientAnchor.AnchorType.MOVE_AND_RESIZE);
|
||||
|
||||
anchor.setCol1(cell.getColumnIndex());
|
||||
anchor.setRow1(cell.getRowIndex());
|
||||
anchor.setCol2(cell.getColumnIndex() + 1);
|
||||
anchor.setRow2(cell.getRowIndex() + 1);
|
||||
|
||||
drawing.createPicture(anchor, pictureIdx);
|
||||
//Creates the top-level drawing patriarch.
|
||||
Drawing drawing = sheet.createDrawingPatriarch();
|
||||
|
||||
//set width to n character widths = count characters * 256
|
||||
int widthUnits = 6 * 5 * 256;
|
||||
sheet.setColumnWidth(cell.getColumnIndex(), widthUnits);
|
||||
|
||||
//set height to n points in twips = n * 20
|
||||
short heightUnits = 6 * 20;
|
||||
cell.getRow().setHeightInPoints(heightUnits);
|
||||
|
||||
// pict.resize();
|
||||
Picture picture = drawing.createPicture(anchor, pictureIdx);
|
||||
picture.resize(factor);
|
||||
|
||||
cell.setCellValue("");
|
||||
}
|
||||
@ -265,6 +296,26 @@ public class ExcelTemplateReportGenerationService {
|
||||
}
|
||||
|
||||
|
||||
private double calculateScale(ByteArrayInputStream imageByteArrayInputStream, float cellWidth, float cellHeight) throws IOException {
|
||||
BufferedImage img = ImageIO.read(imageByteArrayInputStream);
|
||||
|
||||
double imageWidth = img.getWidth();
|
||||
double imageHeight = img.getHeight();
|
||||
|
||||
double widthFactor = (double) cellWidth/ imageWidth;
|
||||
double heightFactor = (double) cellHeight/ imageHeight;
|
||||
|
||||
if (imageWidth < cellWidth && imageHeight < cellHeight) {
|
||||
return 1;
|
||||
} else if (cellWidth > cellHeight) {
|
||||
return heightFactor;
|
||||
} else {
|
||||
return widthFactor;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private String getPlaceholderValue(String placeholder, Dossier project, FileModel fileStatus,
|
||||
Map<String, String> fileAttributePlaceholders,
|
||||
Map<String, String> dossierAttributesPlaceholders) {
|
||||
@ -303,7 +354,6 @@ public class ExcelTemplateReportGenerationService {
|
||||
throw new RuntimeException("unknown placeholder");
|
||||
}
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
public byte[] toByteArray(XSSFWorkbook workbook) {
|
||||
|
||||
|
||||
@ -0,0 +1,29 @@
|
||||
package com.iqser.red.service.redaction.report.v1.server.service;
|
||||
|
||||
public class PixelUtil {
|
||||
|
||||
public static final short EXCEL_COLUMN_WIDTH_FACTOR = 256;
|
||||
public static final short EXCEL_ROW_HEIGHT_FACTOR = 20;
|
||||
public static final int UNIT_OFFSET_LENGTH = 7;
|
||||
public static final int[] UNIT_OFFSET_MAP = new int[] { 0, 36, 73, 109, 146, 182, 219 };
|
||||
|
||||
public static short pixel2WidthUnits(int pxs) {
|
||||
short widthUnits = (short) (EXCEL_COLUMN_WIDTH_FACTOR * (pxs / UNIT_OFFSET_LENGTH));
|
||||
widthUnits += UNIT_OFFSET_MAP[pxs % UNIT_OFFSET_LENGTH];
|
||||
return widthUnits;
|
||||
}
|
||||
|
||||
public static int widthUnits2Pixel(short widthUnits) {
|
||||
int pixels = (widthUnits / EXCEL_COLUMN_WIDTH_FACTOR) * UNIT_OFFSET_LENGTH;
|
||||
int offsetWidthUnits = widthUnits % EXCEL_COLUMN_WIDTH_FACTOR;
|
||||
pixels += Math.floor((float) offsetWidthUnits / ((float) EXCEL_COLUMN_WIDTH_FACTOR / UNIT_OFFSET_LENGTH));
|
||||
return pixels;
|
||||
}
|
||||
|
||||
public static int heightUnits2Pixel(short heightUnits) {
|
||||
int pixels = heightUnits / EXCEL_ROW_HEIGHT_FACTOR;
|
||||
int offsetWidthUnits = heightUnits % EXCEL_ROW_HEIGHT_FACTOR;
|
||||
pixels += Math.floor((float) offsetWidthUnits / ((float) EXCEL_ROW_HEIGHT_FACTOR / UNIT_OFFSET_LENGTH));
|
||||
return pixels;
|
||||
}
|
||||
}
|
||||
@ -18,10 +18,12 @@ import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
||||
import org.apache.poi.util.Dimension2DDouble;
|
||||
import org.apache.poi.util.Units;
|
||||
import org.apache.poi.xwpf.usermodel.*;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
@ -31,6 +33,8 @@ import java.util.regex.Pattern;
|
||||
|
||||
import static com.iqser.red.service.redaction.report.v1.server.service.PlaceholderService.*;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class WordReportGenerationService {
|
||||
@ -196,7 +200,8 @@ public class WordReportGenerationService {
|
||||
XWPFRun run = p.getRuns().get(0);
|
||||
run.setText("", 0);
|
||||
run.addBreak();
|
||||
run.addPicture(is2, XWPFDocument.PICTURE_TYPE_JPEG, "image.jpg", Units.toEMU(200), Units.toEMU(200)); // 200x200 pixels
|
||||
Dimension2DDouble dim = getImageDimension(is2);
|
||||
run.addPicture(is2, XWPFDocument.PICTURE_TYPE_JPEG, "image.jpg", Units.toEMU(dim.getWidth()), Units.toEMU(dim.getHeight()));
|
||||
int size = p.getRuns().size();
|
||||
for (int i = 1; i < size; i++) {
|
||||
p.removeRun(1);
|
||||
@ -328,6 +333,17 @@ public class WordReportGenerationService {
|
||||
}
|
||||
|
||||
|
||||
private Dimension2DDouble getImageDimension(ByteArrayInputStream bais) throws IOException {
|
||||
BufferedImage bufImg = ImageIO.read(bais);
|
||||
bais.reset();
|
||||
|
||||
double width = bufImg.getWidth();
|
||||
double height = bufImg.getHeight();
|
||||
|
||||
return new Dimension2DDouble(width, height);
|
||||
}
|
||||
|
||||
|
||||
private void setText(XWPFTableCell cell, String value) {
|
||||
|
||||
cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
|
||||
|
||||
@ -12,7 +12,6 @@ import java.util.Arrays;
|
||||
import java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
@ -34,12 +33,10 @@ import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.Re
|
||||
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.Dossier;
|
||||
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.DossierAttribute;
|
||||
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.DossierAttributeType;
|
||||
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.file.FileAttribute;
|
||||
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.file.FileAttributeConfig;
|
||||
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.file.FileAttributeType;
|
||||
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.dossier.file.FileModel;
|
||||
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.legalbasis.LegalBasis;
|
||||
import com.iqser.red.service.persistence.service.v1.api.model.dossiertemplate.legalbasis.LegalBasisMapping;
|
||||
import com.iqser.red.service.redaction.report.v1.api.model.ReportType;
|
||||
import com.iqser.red.service.redaction.report.v1.server.client.DossierAttributesClient;
|
||||
import com.iqser.red.service.redaction.report.v1.server.client.DossierAttributesConfigClient;
|
||||
@ -129,7 +126,7 @@ public class RedactionReportIntegrationTest {
|
||||
.label("label2")
|
||||
.editable(true)
|
||||
.type(DossierAttributeType.IMAGE)
|
||||
.placeholder("{{dossier.attribute.image}}")
|
||||
.placeholder("{{dossier.attribute.Signature}}")
|
||||
.build();
|
||||
|
||||
|
||||
@ -209,7 +206,7 @@ public class RedactionReportIntegrationTest {
|
||||
String templateId = "templateId";
|
||||
String dossierId = "dossierId";
|
||||
|
||||
ClassPathResource templateResource = new ClassPathResource("templates/Excel Report.xlsx");
|
||||
ClassPathResource templateResource = new ClassPathResource("templates/TestReport.xlsx");
|
||||
XSSFWorkbook workbook = new XSSFWorkbook(templateResource.getInputStream());
|
||||
|
||||
ClassPathResource legalBasisMappingResource = new ClassPathResource("files/legalBasisMapping.json");
|
||||
@ -219,7 +216,7 @@ public class RedactionReportIntegrationTest {
|
||||
List<ReportRedactionEntry> reportEntries2 = redactionLogConverterService.convertAndSort(redactionLog2, legalBasisMapping);
|
||||
|
||||
DossierAttributeConfig dossierAttributeConfig = new DossierAttributeConfig("id", "label", true, "{{dossier.attribute.name}}", DossierAttributeType.TEXT, dossierTemplateId);//
|
||||
DossierAttributeConfig dossierAttributeConfig2 = new DossierAttributeConfig("id2", "label2", false, "{{dossier.attribute.image}}", DossierAttributeType.IMAGE, dossierTemplateId);
|
||||
DossierAttributeConfig dossierAttributeConfig2 = new DossierAttributeConfig("id2", "label2", false, "{{dossier.attribute.Signature}}", DossierAttributeType.IMAGE, dossierTemplateId);
|
||||
when(dossierAttributesConfigClient.getDossierAttributes(dossierTemplateId)).thenReturn(List.of(dossierAttributeConfig, dossierAttributeConfig2));
|
||||
|
||||
DossierAttribute dossierAttribute = new DossierAttribute(dossierId, dossierAttributeConfig.getId(), "Michael");
|
||||
@ -245,7 +242,7 @@ public class RedactionReportIntegrationTest {
|
||||
excelTemplateReportGenerationService.generateReport(reportEntries2, "dossierTemplateId", workbook, fileModel2, dossier, true);
|
||||
byte[] excelTemplateReport = excelTemplateReportGenerationService.toByteArray(workbook);
|
||||
|
||||
try (FileOutputStream fileOutputStream = new FileOutputStream(getTemporaryDirectory() + "/report_excel_template.xlsx")) {
|
||||
try (FileOutputStream fileOutputStream = new FileOutputStream(getTemporaryDirectory() + "/test_report_excel_template.xlsx")) {
|
||||
fileOutputStream.write(excelTemplateReport);
|
||||
}
|
||||
}
|
||||
@ -272,7 +269,7 @@ public class RedactionReportIntegrationTest {
|
||||
List<ReportRedactionEntry> reportEntries2 = redactionLogConverterService.convertAndSort(redactionLog2, legalBasisMapping);
|
||||
|
||||
DossierAttributeConfig dossierAttributeConfig = new DossierAttributeConfig("id", "label", true, "{{dossier.attribute.name}}", DossierAttributeType.TEXT, dossierTemplateId);
|
||||
DossierAttributeConfig dossierAttributeConfig2 = new DossierAttributeConfig("id2", "label2", false, "{{dossier.attribute.image}}", DossierAttributeType.IMAGE, dossierTemplateId);
|
||||
DossierAttributeConfig dossierAttributeConfig2 = new DossierAttributeConfig("id2", "label2", false, "{{dossier.attribute.Signature}}", DossierAttributeType.IMAGE, dossierTemplateId);
|
||||
when(dossierAttributesConfigClient.getDossierAttributes(dossierTemplateId)).thenReturn(List.of(dossierAttributeConfig, dossierAttributeConfig2));
|
||||
DossierAttribute dossierAttribute = new DossierAttribute(dossierId, "id", "Michael");
|
||||
DossierAttribute dossierAttribute2 = new DossierAttribute(dossierId, "id2", Base64.getEncoder().encodeToString(IOUtils.toByteArray(imageResource.getInputStream())));
|
||||
@ -412,11 +409,11 @@ public class RedactionReportIntegrationTest {
|
||||
public void testIuclidReport() {
|
||||
String dossierTemplateId = "dossierTemplateId";
|
||||
|
||||
ClassPathResource redactionLogResource = new ClassPathResource("files/redactionLog.json");
|
||||
ClassPathResource redactionLogResource = new ClassPathResource("files/S11RedactionLog.json");
|
||||
|
||||
RedactionLog redactionLog = objectMapper.readValue(redactionLogResource.getInputStream(), RedactionLog.class);
|
||||
|
||||
ClassPathResource legalBasisMappingResource = new ClassPathResource("files/legalBasisMapping.json");
|
||||
ClassPathResource legalBasisMappingResource = new ClassPathResource("files/S1116LegalBasis.json");
|
||||
|
||||
List<LegalBasis> legalBasisMapping = objectMapper.readValue(legalBasisMappingResource.getInputStream(), new TypeReference<>() {
|
||||
});
|
||||
@ -433,7 +430,7 @@ public class RedactionReportIntegrationTest {
|
||||
when(fileAttributesConfigClient.getFileAttributeConfigs(dossierTemplateId)).thenReturn(new ArrayList<>());
|
||||
|
||||
|
||||
FileModel fileStatus = FileModel.builder().filename("filename").build();
|
||||
FileModel fileStatus = FileModel.builder().filename("VV123456").build();
|
||||
|
||||
Dossier project = Dossier.builder().id("dossierId").dossierName("projectName").build();
|
||||
|
||||
@ -455,7 +452,7 @@ public class RedactionReportIntegrationTest {
|
||||
.build();
|
||||
byte[] report = wordReportGenerationService.generateReport(ReportType.WORD_SINGLE_FILE, reportEntries, dossierTemplateId, reportTemplate, fileStatus, project);
|
||||
|
||||
try (FileOutputStream fileOutputStream = new FileOutputStream(getTemporaryDirectory() + "/iuclid_report.docx")) {
|
||||
try (FileOutputStream fileOutputStream = new FileOutputStream(getTemporaryDirectory() + "/iuclid_report_2.docx")) {
|
||||
fileOutputStream.write(report);
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 6.7 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.0 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 8.4 KiB |
Binary file not shown.
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user