package eu.eudat.documents.word; import eu.eudat.documents.types.ParagraphStyle; import eu.eudat.documents.types.TextStyle; import eu.eudat.models.user.components.datasetprofile.Field; import eu.eudat.models.user.components.datasetprofile.FieldSet; import eu.eudat.models.user.components.datasetprofile.Section; import eu.eudat.models.user.composite.DatasetProfilePage; import eu.eudat.models.user.composite.PagedDatasetProfile; import eu.eudat.services.forms.VisibilityRuleService; import eu.eudat.utilities.interfaces.ApplierWithValue; import org.apache.poi.xwpf.usermodel.*; 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 java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.math.BigInteger; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Created by ikalyvas on 2/26/2018. */ public class WordBuilder { private Map> options = new HashMap<>(); private CTAbstractNum cTAbstractNum; private BigInteger numId; public WordBuilder() { this.cTAbstractNum = CTAbstractNum.Factory.newInstance(); this.cTAbstractNum.setAbstractNumId(BigInteger.valueOf(1)); } private void buildOptions() { this.options.put(ParagraphStyle.TEXT, (mainDocumentPart, item) -> { XWPFParagraph paragraph = mainDocumentPart.createParagraph(); XWPFRun run = paragraph.createRun(); run.setText(item); run.setFontSize(11); return paragraph; }); this.options.put(ParagraphStyle.TITLE, (mainDocumentPart, item) -> { XWPFParagraph paragraph = mainDocumentPart.createParagraph(); XWPFRun run = paragraph.createRun(); run.setText(item); run.setBold(true); run.setFontSize(14); return paragraph; }); this.options.put(ParagraphStyle.HEADER1, (mainDocumentPart, item) -> { XWPFParagraph paragraph = mainDocumentPart.createParagraph(); XWPFRun run = paragraph.createRun(); run.setText(item); run.setBold(true); run.setFontSize(12); run.setUnderline(UnderlinePatterns.SINGLE); return paragraph; }); this.options.put(ParagraphStyle.HEADER2, (mainDocumentPart, item) -> { XWPFParagraph paragraph = mainDocumentPart.createParagraph(); XWPFRun run = paragraph.createRun(); run.setText(item); run.setBold(true); run.setFontSize(12); run.setUnderline(UnderlinePatterns.SINGLE); return paragraph; }); this.options.put(ParagraphStyle.HEADER3, (mainDocumentPart, item) -> { XWPFParagraph paragraph = mainDocumentPart.createParagraph(); XWPFRun run = paragraph.createRun(); run.setText(item); run.setBold(true); run.setFontSize(11); run.setUnderline(UnderlinePatterns.SINGLE); return paragraph; }); this.options.put(ParagraphStyle.FOOTER, (mainDocumentPart, item) -> { XWPFParagraph paragraph = mainDocumentPart.createParagraph(); XWPFRun run = paragraph.createRun(); run.setText(item); return paragraph; }); } public File build(PagedDatasetProfile pagedDatasetProfile, String label, VisibilityRuleService visibilityRuleService) throws IOException { XWPFDocument document = new XWPFDocument(new FileInputStream((WordBuilder.class.getClassLoader().getResource("documents/h2020.docx")).getFile())); this.buildOptions(); createPages(pagedDatasetProfile.getPages(), document, true, visibilityRuleService); XWPFAbstractNum abstractNum = new XWPFAbstractNum(cTAbstractNum); XWPFNumbering numbering = document.createNumbering(); BigInteger abstractNumID = numbering.addAbstractNum(abstractNum); this.numId = numbering.addNum(abstractNumID); createPages(pagedDatasetProfile.getPages(), document, false, visibilityRuleService); File exportFile = new File(label); FileOutputStream out = new FileOutputStream(exportFile); document.write(out); out.close(); return exportFile; } public void createPages(List datasetProfilePages, XWPFDocument mainDocumentPart, Boolean createListing, VisibilityRuleService visibilityRuleService) { //if (createListing) this.addListing(mainDocumentPart, 0, false, true); datasetProfilePages.forEach(item -> { createSections(item.getSections(), mainDocumentPart, ParagraphStyle.TITLE, 0, createListing, visibilityRuleService); }); } public void createSections(List
sections, XWPFDocument mainDocumentPart, ParagraphStyle style, Integer indent, Boolean createListing, VisibilityRuleService visibilityRuleService) { if (createListing) this.addListing(mainDocumentPart, indent, false, true); BigInteger listing = numId; sections.forEach(section -> { if (visibilityRuleService.isElementVisible(section.getId())) { if (!createListing) { XWPFParagraph paragraph = addParagraphContent(section.getTitle(), mainDocumentPart, style, listing); CTDecimalNumber number = paragraph.getCTP().getPPr().getNumPr().addNewIlvl(); number.setVal(BigInteger.valueOf(indent)); } createSections(section.getSections(), mainDocumentPart, ParagraphStyle.HEADER2, 1, createListing, visibilityRuleService); createCompositeFields(section.getCompositeFields(), mainDocumentPart, 2, createListing, visibilityRuleService); } }); } public void createCompositeFields(List
compositeFields, XWPFDocument mainDocumentPart, Integer indent, Boolean createListing, VisibilityRuleService visibilityRuleService) { if (createListing) this.addListing(mainDocumentPart, indent, true, true); compositeFields.forEach(compositeField -> { if (visibilityRuleService.isElementVisible(compositeField.getId())) { if (compositeField.getTitle() != null && !compositeField.getTitle().isEmpty() && !createListing) { XWPFParagraph paragraph = addParagraphContent(compositeField.getTitle(), mainDocumentPart, ParagraphStyle.HEADER3, numId); CTDecimalNumber number = paragraph.getCTP().getPPr().getNumPr().addNewIlvl(); number.setVal(BigInteger.valueOf(indent)); } createFields(compositeField.getFields(), mainDocumentPart, 3, createListing, visibilityRuleService); } }); } public void createFields(List fields, XWPFDocument mainDocumentPart, Integer indent, Boolean createListing, VisibilityRuleService visibilityRuleService) { if (createListing) this.addListing(mainDocumentPart, indent, false, false); fields.forEach(field -> { if (visibilityRuleService.isElementVisible(field.getId())) { if (!createListing) { XWPFParagraph paragraph = addParagraphContent(field.getValue() == null ? "" : field.getValue(), mainDocumentPart, ParagraphStyle.TEXT, numId); CTDecimalNumber number = paragraph.getCTP().getPPr().getNumPr().addNewIlvl(); number.setVal(BigInteger.valueOf(indent)); } } }); } 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); return paragraph; } public void addStyling(List styles, String color) { } public void addListing(XWPFDocument document, int indent, Boolean question, Boolean hasIndication) { //this.cTAbstractNum.setAbstractNumId(BigInteger.valueOf(indent)); CTLvl cTLvl = this.cTAbstractNum.addNewLvl(); String textLevel = ""; for (int i = 0; i <= indent; i++) { textLevel += "%" + (i + 1) + "."; } if (question) { cTLvl.addNewNumFmt().setVal(STNumberFormat.DECIMAL); cTLvl.addNewLvlText().setVal("Q " + textLevel); cTLvl.addNewStart().setVal(BigInteger.valueOf(1)); cTLvl.setIlvl(BigInteger.valueOf(indent)); } else if (!question && hasIndication) { cTLvl.addNewNumFmt().setVal(STNumberFormat.DECIMAL); cTLvl.addNewLvlText().setVal(textLevel); cTLvl.addNewStart().setVal(BigInteger.valueOf(1)); cTLvl.setIlvl(BigInteger.valueOf(indent)); } if (!question && !hasIndication) { cTLvl.addNewNumFmt().setVal(STNumberFormat.NONE); cTLvl.addNewLvlText().setVal(""); cTLvl.addNewStart().setVal(BigInteger.valueOf(1)); cTLvl.setIlvl(BigInteger.valueOf(indent)); } /*if (this.numId == null) { XWPFAbstractNum abstractNum = new XWPFAbstractNum(cTAbstractNum); XWPFNumbering numbering = document.createNumbering(); BigInteger abstractNumID = numbering.addAbstractNum(abstractNum); this.numId = numbering.addNum(abstractNumID); }*/ } }