Created
November 11, 2018 20:23
-
-
Save hedza06/0406e7fe6a761fad1639dedb5cb1d644 to your computer and use it in GitHub Desktop.
DOCx templating / Replacing placeholders with real data
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.apache.poi.openxml4j.util.ZipSecureFile; | |
import org.apache.poi.xwpf.usermodel.*; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
import org.springframework.core.io.ClassPathResource; | |
import java.util.Optional; | |
import java.io.ByteArrayOutputStream; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import java.nio.file.Files; | |
import java.nio.file.Path; | |
import java.nio.file.Paths; | |
import java.time.LocalDateTime; | |
import java.time.format.DateTimeFormatter; | |
import java.util.ArrayList; | |
import java.util.List; | |
import java.util.Map; | |
import java.util.stream.Collectors; | |
import java.util.stream.Stream; | |
/** | |
* @class WordService | |
* @author Heril Muratović | |
**/ | |
public class DocxTemplateService { | |
private static final Logger LOGGER = LoggerFactory.getLogger(WordService.class); | |
/** | |
* Method for generating DocX report by replacing data in existing template | |
* | |
* @param docXTemplateFileWithExtension given name of docX template with extension | |
* @param dataParams given map of data parameters that need to be replacement for docX placeholders | |
* @return generated report name | |
* @throws IOException input|output exception | |
**/ | |
public Optional<String> generateReport(String docXTemplateFileWithExtension, Map<String, String> dataParams) throws IOException | |
{ | |
// get docx template from file system | |
ClassPathResource pathResource = new ClassPathResource("your_folder_name/" + docXTemplateFileWithExtension); | |
InputStream inputStream = pathResource.getInputStream(); | |
ZipSecureFile.setMinInflateRatio(-1.0d); | |
ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); | |
try (XWPFDocument xwpfDocument = new XWPFDocument(inputStream)) | |
{ | |
replacePlaceholdersInParagraphs(dataParams, xwpfDocument); | |
replacePlaceholderInTables(dataParams, xwpfDocument); | |
xwpfDocument.write(outputStream); | |
// generate file name | |
String generatedFileName = "report" | |
.concat("_") | |
.concat(LocalDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) | |
.concat(".") | |
.concat("docx") | |
); | |
// store report to file system | |
Path path = Paths.get("your_report_path/" + generatedFileName); | |
Files.write(path, outputStream.toByteArray()); | |
return generatedFileName; | |
} | |
catch (Exception e) | |
{ | |
LOGGER.error("Error occurred while generating report: {}", e.getMessage()); | |
return Optional.empty(); | |
} | |
} | |
/** | |
* Method for replacing docx placeholders with given data parameters in every docx paragraph | |
* | |
* @param dataParams given data to be replaced with template placeholders | |
* @param xwpfDocument docx template document | |
**/ | |
private void replacePlaceholdersInParagraphs(Map<String, String> dataParams, XWPFDocument xwpfDocument) | |
{ | |
for (Map.Entry<String, String> entry : dataParams.entrySet()) | |
{ | |
for (XWPFParagraph paragraph : xwpfDocument.getParagraphs()) | |
{ | |
for (XWPFRun run : paragraph.getRuns()) | |
{ | |
String text = run.text(); | |
if ( | |
text != null | |
&& text.contains(entry.getKey()) | |
&& entry.getValue() != null | |
&& !entry.getValue().isEmpty() | |
) | |
{ | |
text = text.replace(entry.getKey(), entry.getValue()); | |
run.setText(text, 0); | |
} | |
} | |
} | |
} | |
} | |
/** | |
* Method for replacing docx placeholders with given data parameters in docx table | |
* | |
* @param dataParams given data to be replaced with template placeholders | |
* @param xwpfDocument docx template document | |
**/ | |
private void replacePlaceholderInTables(Map<String, String> dataParams, XWPFDocument xwpfDocument) | |
{ | |
for (Map.Entry<String, String> entry : dataParams.entrySet()) | |
{ | |
for (XWPFTable xwpfTable : xwpfDocument.getTables()) | |
{ | |
for (XWPFTableRow xwpfTableRow : xwpfTable.getRows()) | |
{ | |
for (XWPFTableCell xwpfTableCell : xwpfTableRow.getTableCells()) | |
{ | |
for (XWPFParagraph xwpfParagraph : xwpfTableCell.getParagraphs()) | |
{ | |
for (XWPFRun xwpfRun : xwpfParagraph.getRuns()) | |
{ | |
String text = xwpfRun.text(); | |
if ( | |
text != null | |
&& text.contains(entry.getKey()) | |
&& entry.getValue() != null | |
&& !entry.getValue().isEmpty() | |
) | |
{ | |
text = text.replace(entry.getKey(), entry.getValue()); | |
xwpfRun.setText(text, 0); | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment