1.技術(shù)freemarker
代碼 https://gitee.com/J-summit/note-sty-blogs/tree/master/src/main/java/tech/cn/note/html

image.png
參考https://www.cnblogs.com/itdragon/p/7750903.html
http://freemarker.foofun.cn/index.html
2.代碼實現(xiàn)
@Service
public class FreeMakerDataFillServiceImpl implements FreeMakerDataFillService {
private final List<DocumentConvert> convertList;
@Autowired
public FreeMakerDataFillServiceImpl(List<DocumentConvert> convertList) {
this.convertList = convertList;
}
@Override
public byte[] processToByte(File templateFile, Map<String, Object> dataSource) {
return doProcess(templateFile.getParent(), templateFile.getName(), dataSource);
}
@Override
public byte[] processToByte(String templatePath, Map<String, Object> dataSource) {
File templateFile = checkTemplateFile(templatePath);
return doProcess(templateFile.getParent(), templateFile.getName(), dataSource);
}
@Override
public byte[] processToByte(String templateDir, String templateName, Map<String, Object> dataSource) {
checkTemplateFile(templateDir, templateName);
return doProcess(templateDir, templateName, dataSource);
}
@Override
public ByteArrayInputStream processToStream(File templateFile, Map<String, Object> dataSource) {
byte[] outBytes = processToByte(templateFile, dataSource);
if (outBytes == null || outBytes.length < 1) {return null;}
//轉(zhuǎn)換為字節(jié)流
return new ByteArrayInputStream(outBytes);
}
@Override
public ByteArrayInputStream processToStream(String templatePath, Map<String, Object> dataSource) {
byte[] outBytes = processToByte(templatePath, dataSource);
if (outBytes == null || outBytes.length < 1){ return null;}
//轉(zhuǎn)換為字節(jié)流
return new ByteArrayInputStream(outBytes);
}
@Override
public ByteArrayInputStream processToStream(String templateDir, String templateName, Map<String, Object> dataSource) {
byte[] outBytes = processToByte(templateDir, templateName, dataSource);
if (outBytes == null || outBytes.length < 1) {return null;}
//轉(zhuǎn)換為字節(jié)流
return new ByteArrayInputStream(outBytes);
}
/**
* 填充數(shù)據(jù)至模板中
*/
private byte[] doProcess(String templateDir, String templateName, Map<String, Object> dataSource) {
DocumentConfiguration fillConfig;
StringWriter outWriter;
try {
log.debug("模板名稱:{},填充數(shù)據(jù)開始,data is {}", templateName, JSONUtil.parse(dataSource));
//填充數(shù)據(jù)轉(zhuǎn)換自定義方法
if (CollUtil.isNotEmpty(convertList)) {
convertList.forEach(c -> dataSource.put(c.getConvertName(), c));
}
//根據(jù)模板目錄獲取對象
fillConfig = new DocumentConfiguration(templateDir);
outWriter = new StringWriter();
//獲取模板對象
Template template = fillConfig.getTemplate(templateName);
//填充數(shù)據(jù)至模板中
template.process(dataSource, outWriter);
log.info("模板名稱:{},填充數(shù)據(jù)結(jié)束...", templateName);
return outWriter.toString().getBytes(StandardCharsets.UTF_8);
} catch (Exception e) {
String msg = String.format("填充模板數(shù)據(jù)出錯, 模板名稱:%1s", templateName);
log.error(msg + ", 出錯信息: " + e);
throw new RuntimeException(msg);
}
}
/**
* 檢查模板路徑
*/
private File checkTemplateFile(String templatePath) {
if (StringUtils.isBlank(templatePath)) {
throw new RuntimeException("數(shù)據(jù)填充模板路徑不允許為空");
}
File templateFile = new File(templatePath);
if (!templateFile.exists()) {
throw new RuntimeException("數(shù)據(jù)填充模板文件不存在");
}
return templateFile;
}
/**
* 檢查模板路徑
*/
private File checkTemplateFile(String templateDir, String templateName) {
if (StringUtils.isBlank(templateDir)) {
throw new RuntimeException("數(shù)據(jù)填充模板目錄不允許為空");
}
if (StringUtils.isBlank(templateName)) {
throw new RuntimeException("數(shù)據(jù)填充模板名稱不允許為空");
}
String templatePath = String.format("%1s%2s%3s", templateDir, File.separator, templateName);
File templateFile = new File(templatePath);
if (!templateFile.exists()) {
throw new RuntimeException("數(shù)據(jù)填充模板文件不存在");
}
return templateFile;
}
}