attach images in word export

This commit is contained in:
Bernaldo Mihasi 2022-03-17 10:47:50 +02:00
parent 7f9e12c731
commit 65b4e58aad
4 changed files with 89 additions and 25 deletions

View File

@ -1173,7 +1173,7 @@ public class DataManagementPlanManager {
}
public FileEnvelope getWordDocument(String id, Principal principal, ConfigLoader configLoader, Boolean versioned) throws IOException {
WordBuilder wordBuilder = new WordBuilder();
WordBuilder wordBuilder = new WordBuilder(this.environment);
VisibilityRuleService visibilityRuleService = new VisibilityRuleServiceImpl();
DatasetWizardModel dataset = new DatasetWizardModel();
XWPFDocument document = configLoader.getDocument();

View File

@ -397,7 +397,7 @@ public class DatasetManager {
}
private XWPFDocument getWordDocument(ConfigLoader configLoader, eu.eudat.data.entities.Dataset datasetEntity, VisibilityRuleService visibilityRuleService) throws IOException {
WordBuilder wordBuilder = new WordBuilder();
WordBuilder wordBuilder = new WordBuilder(this.environment);
DatasetWizardModel dataset = new DatasetWizardModel();
XWPFDocument document = configLoader.getDocument();
@ -481,7 +481,7 @@ public class DatasetManager {
}
private XWPFDocument getLightWordDocument(ConfigLoader configLoader, DatasetWizardModel dataset, VisibilityRuleService visibilityRuleService) throws IOException {
WordBuilder wordBuilder = new WordBuilder();
WordBuilder wordBuilder = new WordBuilder(this.environment);
XWPFDocument document = configLoader.getDocument();
// Space below Dataset title.

View File

@ -4,7 +4,7 @@ package eu.eudat.logic.utilities.documents.types;
* Created by ikalyvas on 2/26/2018.
*/
public enum ParagraphStyle {
TEXT(0), HEADER1(1), HEADER2(2), HEADER3(3), HEADER4(4), TITLE(5), FOOTER(6), COMMENT(7), HEADER5(8), HEADER6(9), HTML(10);
TEXT(0), HEADER1(1), HEADER2(2), HEADER3(3), HEADER4(4), TITLE(5), FOOTER(6), COMMENT(7), HEADER5(8), HEADER6(9), HTML(10), IMAGE(11);
private Integer value;
@ -40,6 +40,8 @@ public enum ParagraphStyle {
return HEADER6;
case 10:
return HTML;
case 11:
return IMAGE;
default:
throw new RuntimeException("Unsupported ParagraphStyle Code");
}

View File

@ -7,51 +7,57 @@ import eu.eudat.logic.utilities.documents.types.ParagraphStyle;
import eu.eudat.logic.utilities.interfaces.ApplierWithValue;
import eu.eudat.models.data.components.commons.datafield.CheckBoxData;
import eu.eudat.models.data.components.commons.datafield.ComboBoxData;
import eu.eudat.models.data.components.commons.datafield.UploadData;
import eu.eudat.models.data.components.commons.datafield.WordListData;
import eu.eudat.models.data.user.components.datasetprofile.Field;
import eu.eudat.models.data.user.components.datasetprofile.FieldSet;
import eu.eudat.models.data.user.components.datasetprofile.Section;
import eu.eudat.models.data.user.composite.DatasetProfilePage;
import eu.eudat.models.data.user.composite.PagedDatasetProfile;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.*;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTAbstractNum;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDecimalNumber;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTLvl;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STNumberFormat;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.env.Environment;
import org.springframework.http.MediaType;
import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.time.temporal.TemporalAccessor;
import java.util.*;
import java.util.stream.Collectors;
public class WordBuilder {
private static final Logger logger = LoggerFactory.getLogger(WordBuilder.class);
private Map<ParagraphStyle, ApplierWithValue<XWPFDocument, String, XWPFParagraph>> options = new HashMap<>();
private Map<ParagraphStyle, ApplierWithValue<XWPFDocument, Object, XWPFParagraph>> options = new HashMap<>();
private CTAbstractNum cTAbstractNum;
private BigInteger numId;
private Integer indent;
private static final ObjectMapper mapper = new ObjectMapper();
public WordBuilder() {
public WordBuilder(Environment environment) {
this.cTAbstractNum = CTAbstractNum.Factory.newInstance();
this.cTAbstractNum.setAbstractNumId(BigInteger.valueOf(1));
this.indent = 0;
this.buildOptions();
this.buildOptions(environment);
}
private void buildOptions() {
private void buildOptions(Environment environment) {
this.options.put(ParagraphStyle.TEXT, (mainDocumentPart, item) -> {
XWPFParagraph paragraph = mainDocumentPart.createParagraph();
XWPFRun run = paragraph.createRun();
@ -61,7 +67,7 @@ public class WordBuilder {
return paragraph;
});
this.options.put(ParagraphStyle.HTML, (mainDocumentPart, item) -> {
Document htmlDoc = Jsoup.parse(item.replaceAll("\n", "<br>"));
Document htmlDoc = Jsoup.parse(((String)item).replaceAll("\n", "<br>"));
HtmlToWorldBuilder htmlToWorldBuilder = HtmlToWorldBuilder.convert(mainDocumentPart, htmlDoc, indent > 0 ? (indent/2.0F) * 0.8F : 0.8F);
return htmlToWorldBuilder.getParagraph();
});
@ -70,7 +76,7 @@ public class WordBuilder {
paragraph.setStyle("Title");
paragraph.setAlignment(ParagraphAlignment.CENTER);
XWPFRun run = paragraph.createRun();
run.setText(item);
run.setText((String)item);
run.setBold(true);
run.setFontSize(14);
return paragraph;
@ -79,7 +85,7 @@ public class WordBuilder {
XWPFParagraph paragraph = mainDocumentPart.createParagraph();
paragraph.setStyle("Heading1");
XWPFRun run = paragraph.createRun();
run.setText(item);
run.setText((String)item);
// run.setBold(true);
// run.setFontSize(12);
// run.setStyle("0");
@ -107,7 +113,7 @@ public class WordBuilder {
XWPFParagraph paragraph = mainDocumentPart.createParagraph();
paragraph.setStyle("Heading4");
XWPFRun run = paragraph.createRun();
run.setText(item);
run.setText((String)item);
return paragraph;
});
this.options.put(ParagraphStyle.HEADER5, (mainDocumentPart, item) -> {
@ -127,7 +133,7 @@ public class WordBuilder {
this.options.put(ParagraphStyle.FOOTER, (mainDocumentPart, item) -> {
XWPFParagraph paragraph = mainDocumentPart.createParagraph();
XWPFRun run = paragraph.createRun();
run.setText(item);
run.setText((String)item);
return paragraph;
});
this.options.put(ParagraphStyle.COMMENT, (mainDocumentPart, item) -> {
@ -137,6 +143,41 @@ public class WordBuilder {
run.setItalic(true);
return paragraph;
});
this.options.put(ParagraphStyle.IMAGE, (mainDocumentPart, item) -> {
XWPFParagraph paragraph = mainDocumentPart.createParagraph();
XWPFRun run = paragraph.createRun();
String imageId = ((Map<String, String>)item).get("id");
String fileName = ((Map<String, String>)item).get("name");
int format = 0;
if (fileName.endsWith(".jpeg") || fileName.endsWith(".jpg")) {
format = org.apache.poi.xwpf.usermodel.Document.PICTURE_TYPE_JPEG;
} else if (fileName.endsWith(".png")) {
format = org.apache.poi.xwpf.usermodel.Document.PICTURE_TYPE_PNG;
} else if (fileName.endsWith(".gif")) {
format = org.apache.poi.xwpf.usermodel.Document.PICTURE_TYPE_GIF;
} else if (fileName.endsWith(".tiff")) {
format = org.apache.poi.xwpf.usermodel.Document.PICTURE_TYPE_TIFF;
}
try {
FileInputStream image = new FileInputStream(environment.getProperty("file.storage") + imageId);
ImageInputStream iis = ImageIO.createImageInputStream(new File(environment.getProperty("file.storage") + imageId));
Iterator<ImageReader> readers = ImageIO.getImageReaders(iis);
if (readers.hasNext()) {
ImageReader reader = readers.next();
reader.setInput(iis);
int pageWidth = Math.round(mainDocumentPart.getDocument().getBody().getSectPr().getPgSz().getW().intValue() / (float)20);
int imageWidth = reader.getWidth(0);
int width = Math.min(imageWidth, pageWidth);
int pageHeight = Math.round(mainDocumentPart.getDocument().getBody().getSectPr().getPgSz().getH().intValue() / (float)20);
int imageHeight = reader.getHeight(0);
int height = Math.min(imageHeight, pageHeight);
run.addPicture(image, format, fileName, Units.toEMU(width), Units.toEMU(height));
}
} catch (IOException | InvalidFormatException e){
logger.error(e.getMessage(), e);
}
return paragraph;
});
}
public XWPFDocument build(XWPFDocument document, PagedDatasetProfile pagedDatasetProfile, VisibilityRuleService visibilityRuleService) throws IOException {
@ -254,7 +295,27 @@ public class WordBuilder {
if (visibilityRuleService.isElementVisible(field.getId())) {
if (!createListing) {
try {
if (field.getValue() != null && !field.getValue().toString().isEmpty()) {
if(field.getViewStyle().getRenderStyle().equals("upload")){
boolean isImage = false;
for(UploadData.Option type: ((UploadData)field.getData()).getTypes()){
String fileFormat = type.getValue();
if(fileFormat.equals(MediaType.IMAGE_JPEG_VALUE) || fileFormat.equals(MediaType.IMAGE_PNG_VALUE) || fileFormat.equals(MediaType.IMAGE_GIF_VALUE)){
isImage = true;
break;
}
}
if(isImage){
if (!field.getValue().toString().isEmpty()) {
XWPFParagraph paragraph = addParagraphContent(mapper.convertValue(field.getValue(), Map.class), mainDocumentPart, ParagraphStyle.IMAGE, numId);
if (paragraph != null) {
CTDecimalNumber number = paragraph.getCTP().getPPr().getNumPr().addNewIlvl();
number.setVal(BigInteger.valueOf(indent));
hasValue = true;
}
}
}
}
else if (field.getValue() != null && !field.getValue().toString().isEmpty()) {
this.indent = indent;
String format = this.formatter(field);
if(format != null && !format.isEmpty()){
@ -281,9 +342,12 @@ public class WordBuilder {
return hasValue;
}
public XWPFParagraph addParagraphContent(String text, XWPFDocument mainDocumentPart, ParagraphStyle style, BigInteger numId) {
if (text != null && !text.isEmpty()) {
XWPFParagraph paragraph = this.options.get(style).apply(mainDocumentPart, text);
public XWPFParagraph addParagraphContent(Object content, XWPFDocument mainDocumentPart, ParagraphStyle style, BigInteger numId) {
if (content != null) {
if (content instanceof String && ((String)content).isEmpty()) {
return null;
}
XWPFParagraph paragraph = this.options.get(style).apply(mainDocumentPart, content);
if (paragraph != null) {
if (numId != null) {
paragraph.setNumID(numId);
@ -343,7 +407,6 @@ public class WordBuilder {
comboboxType = ((ComboBoxData) field.getData()).getType();
}
if (comboboxType.equals("autocomplete")) {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
if (field.getValue() == null) return null;
List<Map<String, Object>> mapList = new ArrayList<>();
@ -418,7 +481,6 @@ public class WordBuilder {
case "validation":
if (field.getValue() != null && !field.getValue().toString().isEmpty()) {
Map<String, String> identifierData;
ObjectMapper mapper = new ObjectMapper();
try {
identifierData = mapper.readValue(field.getValue().toString(), HashMap.class);
} catch (Exception ex) {