Skip to content

Instantly share code, notes, and snippets.

@hedza06
Created November 11, 2018 20:23
Show Gist options
  • Save hedza06/0406e7fe6a761fad1639dedb5cb1d644 to your computer and use it in GitHub Desktop.
Save hedza06/0406e7fe6a761fad1639dedb5cb1d644 to your computer and use it in GitHub Desktop.
DOCx templating / Replacing placeholders with real data
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