From c1adbe283aaa817c0e0df2340c4fc4776747d288 Mon Sep 17 00:00:00 2001 From: George Kalampokis Date: Wed, 30 Jun 2021 17:17:17 +0300 Subject: [PATCH] Improvements over MS Word Document export (cherry picked from commit 4e3b98f1ff6b375091fb2445b34aab8ada3f38fd) --- .../managers/DataManagementPlanManager.java | 2 +- .../utilities/documents/word/WordBuilder.java | 89 ++++++++++++------- 2 files changed, 59 insertions(+), 32 deletions(-) diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java index ae7c63c7a..2ef9a576b 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java @@ -1257,7 +1257,7 @@ public class DataManagementPlanManager { if (versioned) { fileName += "_" + dmpEntity.getVersion(); } - fileName = fileName.replaceAll("[^a-zA-Z0-9+ ]", ""); + // fileName = fileName.replaceAll("[^a-zA-Z0-9+ ]", ""); FileEnvelope exportEnvelope = new FileEnvelope(); exportEnvelope.setFilename(fileName + ".docx"); String uuid = UUID.randomUUID().toString(); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/word/WordBuilder.java b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/word/WordBuilder.java index 41675e624..764ac5a6f 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/word/WordBuilder.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/word/WordBuilder.java @@ -144,67 +144,89 @@ public class WordBuilder { private void createSections(List
sections, XWPFDocument mainDocumentPart, ParagraphStyle style, Integer indent, Boolean createListing, VisibilityRuleService visibilityRuleService, Integer page, String sectionString) { if (createListing) this.addListing(mainDocumentPart, indent, false, true); - sections.forEach(section -> { + boolean hasValue = false; + for (Section section: sections) { + int paragraphPos = -1; String tempSectionString = sectionString != null ? sectionString + "." + (section.getOrdinal() + 1) : "" + (section.getOrdinal() + 1); if (visibilityRuleService.isElementVisible(section.getId())) { if (!createListing) { XWPFParagraph paragraph = addParagraphContent(page + "." + tempSectionString + " " + section.getTitle(), mainDocumentPart, style, numId); CTDecimalNumber number = paragraph.getCTP().getPPr().getNumPr().addNewIlvl(); number.setVal(BigInteger.valueOf(indent)); + paragraphPos = mainDocumentPart.getPosOfParagraph(paragraph); } createSections(section.getSections(), mainDocumentPart, ParagraphStyle.HEADER5, 1, createListing, visibilityRuleService, page, tempSectionString); - createCompositeFields(section.getCompositeFields(), mainDocumentPart, 2, createListing, visibilityRuleService, page, tempSectionString); + hasValue = createCompositeFields(section.getCompositeFields(), mainDocumentPart, 2, createListing, visibilityRuleService, page, tempSectionString); + + if (!hasValue && paragraphPos > -1) { + mainDocumentPart.removeBodyElement(paragraphPos); + } } - }); + } } - private void createCompositeFields(List
compositeFields, XWPFDocument mainDocumentPart, Integer indent, Boolean createListing, VisibilityRuleService visibilityRuleService, Integer page, String section) { + private Boolean createCompositeFields(List
compositeFields, XWPFDocument mainDocumentPart, Integer indent, Boolean createListing, VisibilityRuleService visibilityRuleService, Integer page, String section) { if (createListing) this.addListing(mainDocumentPart, indent, true, true); - compositeFields.forEach(compositeField -> { + boolean hasValue = false; + for (FieldSet compositeField: compositeFields) { if (visibilityRuleService.isElementVisible(compositeField.getId()) && hasVisibleFields(compositeField, visibilityRuleService)) { + int paragraphPos = -1; if (compositeField.getTitle() != null && !compositeField.getTitle().isEmpty() && !createListing) { XWPFParagraph paragraph = addParagraphContent(page + "." + section + "." + (compositeField.getOrdinal() +1) + " " + compositeField.getTitle(), mainDocumentPart, ParagraphStyle.HEADER6, numId); CTDecimalNumber number = paragraph.getCTP().getPPr().getNumPr().addNewIlvl(); number.setVal(BigInteger.valueOf(indent)); + paragraphPos = mainDocumentPart.getPosOfParagraph(paragraph); } - createFields(compositeField.getFields(), mainDocumentPart, 3, createListing, visibilityRuleService); + hasValue = createFields(compositeField.getFields(), mainDocumentPart, 3, createListing, visibilityRuleService); if (compositeField.getMultiplicityItems() != null && !compositeField.getMultiplicityItems().isEmpty()) { for (FieldSet multiplicityFieldset : compositeField.getMultiplicityItems()) { - createFields(multiplicityFieldset.getFields(), mainDocumentPart, 3, createListing, visibilityRuleService); + hasValue = createFields(multiplicityFieldset.getFields(), mainDocumentPart, 3, createListing, visibilityRuleService); } } - if (compositeField.getHasCommentField() && compositeField.getCommentFieldValue() != null && !compositeField.getCommentFieldValue().isEmpty() && !createListing) { + if (hasValue && compositeField.getHasCommentField() && compositeField.getCommentFieldValue() != null && !compositeField.getCommentFieldValue().isEmpty() && !createListing) { XWPFParagraph paragraph = addParagraphContent("Comment: " + compositeField.getCommentFieldValue(), mainDocumentPart, ParagraphStyle.COMMENT, numId); CTDecimalNumber number = paragraph.getCTP().getPPr().getNumPr().addNewIlvl(); number.setVal(BigInteger.valueOf(indent)); } + if (!hasValue && paragraphPos > -1) { + mainDocumentPart.removeBodyElement(paragraphPos); + } } - }); + } + return hasValue; } - private void createFields(List fields, XWPFDocument mainDocumentPart, Integer indent, Boolean createListing, VisibilityRuleService visibilityRuleService) { + private Boolean createFields(List fields, XWPFDocument mainDocumentPart, Integer indent, Boolean createListing, VisibilityRuleService visibilityRuleService) { if (createListing) this.addListing(mainDocumentPart, indent, false, false); - fields.forEach(field -> { + boolean hasValue = false; + for (Field field: fields) { if (visibilityRuleService.isElementVisible(field.getId())) { if (!createListing) { try { XWPFParagraph paragraph = addParagraphContent(this.formatter(field), mainDocumentPart, ParagraphStyle.TEXT, numId); - CTDecimalNumber number = paragraph.getCTP().getPPr().getNumPr().addNewIlvl(); - number.setVal(BigInteger.valueOf(indent)); + if (paragraph != null) { + CTDecimalNumber number = paragraph.getCTP().getPPr().getNumPr().addNewIlvl(); + number.setVal(BigInteger.valueOf(indent)); + hasValue = true; + } } catch (IOException e) { logger.error(e.getMessage(), e); } } } - }); + } + return hasValue; } public XWPFParagraph addParagraphContent(String text, XWPFDocument mainDocumentPart, ParagraphStyle style, BigInteger numId) { - XWPFParagraph paragraph = this.options.get(style).apply(mainDocumentPart, text); - if (numId != null) { - paragraph.setNumID(numId); + if (text != null && !text.isEmpty()) { + XWPFParagraph paragraph = this.options.get(style).apply(mainDocumentPart, text); + if (numId != null) { + paragraph.setNumID(numId); + } + return paragraph; } - return paragraph; + return null; } private void addListing(XWPFDocument document, int indent, Boolean question, Boolean hasIndication) { @@ -254,6 +276,7 @@ public class WordBuilder { mapList = Arrays.asList(mapper.readValue(field.getValue().toString(), HashMap[].class)); }catch (Exception e) { logger.warn(e.getMessage(), e); + logger.info("Moving to fallback parsing"); Map map = new HashMap<>(); map.put("label", field.getValue().toString()); mapList.add(map); @@ -304,6 +327,7 @@ public class WordBuilder { WordListData wordListData = (WordListData) field.getData(); if (wordListData.getOptions().isEmpty() && field.getValue() != null) { logger.warn("World List has no values but the field has"); + logger.info("Return value as is"); return field.getValue().toString(); } else if (field.getValue() != null){ ComboBoxData.Option selectedOption = null; @@ -332,21 +356,24 @@ public class WordBuilder { return field.getValue() != null ? field.getValue().toString(): ""; case "datasetIdentifier": case "validation": - Map identifierData; - try { - ObjectMapper mapper = new ObjectMapper(); - identifierData = mapper.readValue(field.getValue().toString(), HashMap.class); - } catch (JsonParseException ex) { - identifierData = new HashMap<>(); - String parsedData = field.getValue().toString().substring(1, field.getValue().toString().length() - 1); - StringTokenizer commaTokens = new StringTokenizer(parsedData, ", "); - while (commaTokens.hasMoreTokens()) { - String token = commaTokens.nextToken(); - StringTokenizer equalTokens = new StringTokenizer(token, "="); - identifierData.put(equalTokens.nextToken(), equalTokens.nextToken()); + if (field.getValue() != null) { + Map identifierData; + try { + ObjectMapper mapper = new ObjectMapper(); + identifierData = mapper.readValue(field.getValue().toString(), HashMap.class); + } catch (JsonParseException ex) { + identifierData = new HashMap<>(); + String parsedData = field.getValue().toString().substring(1, field.getValue().toString().length() - 1); + StringTokenizer commaTokens = new StringTokenizer(parsedData, ", "); + while (commaTokens.hasMoreTokens()) { + String token = commaTokens.nextToken(); + StringTokenizer equalTokens = new StringTokenizer(token, "="); + identifierData.put(equalTokens.nextToken(), equalTokens.nextToken()); + } } + return "id: " + identifierData.get("identifier") + ", Validation Type: " + identifierData.get("type"); } - return "id: " + identifierData.get("identifier") + ", Validation Type: " + identifierData.get("type"); + return ""; } return null; }