1.為什么要寫這一篇呢?
在做一個郵件發送功能的時候,需要發送html郵件,javaMail 發送html 的時候需要有已經生成的html正文,所以需要提前將要發送的內容生成,所以就需要模板引擎來動態填充數據。
public void sendHtmlEmail(String to, String object, String content) { MimeMessage message = mailSender.createMimeMessage();//創建一個MINE消息 try { //true表示需要創建一個multipart message MimeMessageHelper helper = new MimeMessageHelper(message, true); helper.setFrom(from); helper.setTo(to); helper.setSubject(object); helper.setText(content, true); mailSender.send(message); log.info("html郵件發送成功"); } catch (MessagingException e) { log.error("發送html郵件時發生異常!", e); } }
2.引入依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>
ognl 的jar包可能並不需要,在生成過程中報classNotFound ,應該是和我的項目結構有關系,這個包根據實際情況來使用
<dependency> <groupId>ognl</groupId> <artifactId>ognl</artifactId> <version>3.2</version> </dependency>
3.代碼
(1)首先准備一個html模板,需要替換的內容使用themleaf的th表達式來占位。我的工程是springboot 項目,文件位置放在resources/templates,也就是classpath:templates/
<!DOCTYPE html> <html lang="zh" xmlns:th="http://www.thymeleaf.org"> <html> <head> <title>Title</title> <style type="text/css"> td{ width: 80px; height: 25px; align-content: center; } </style> </head> <body> <h4>親愛的<span th:text="${name}"></span>,您<span th:text="${month}"></span>月份的工資如下:</h4> <table border="1" style="border-collapse: collapse" > <tr> <td th:each="item:${th}" th:text="${item}"></td> </tr> <tr> <td th:each="ib:${tb}" th:text="${ib}"></td> </tr> </table> </body> </html>
2.配置模板引擎
@Configuration public class MailConfig { @Bean("myTemplateEngine") public TemplateEngine templateEngine(){ ClassLoaderTemplateResolver resolver = new ClassLoaderTemplateResolver(); resolver.setPrefix("templates/"); resolver.setSuffix(".html"); TemplateEngine engine = new TemplateEngine(); engine.setTemplateResolver(resolver); return engine; } }
為手動生成html文件單獨定義一個模板引擎,其他的使用默認配置。其中制定了模板文件的位置及后綴名,這個配置和application.properties 中配置是一樣的
3.生成html
@PostMapping("/sendEmail")
@ResponseBody
public AjaxResult sendEmail(Integer id) throws IOException {
List<ComponentVo> componentVos = salaryCompnentService.selectComponentSum(id);
List<String> th = Lists.newArrayList();
List<String> tb = Lists.newArrayList();
for (int i = 0; i < componentVos.size(); i++) {
ComponentVo vo = componentVos.get(i);
th.add(i, vo.getName());
tb.add(i, vo.getAmount());
}
SalaryCalculateVo salaryCalculate = salaryService.selectSalaryById(id);
Context context = new Context();
context.setVariable("name", salaryCalculate.getEmpName());
context.setVariable("month", salaryCalculate.getWorkMonth());
context.setVariable("th", th);
context.setVariable("tb", tb);
String res = engine.process("mailTeamlate", context);
salaryService.sendEmail(id,res, salaryCalculate.getWorkMonth() + "工資條", salaryCalculate.getEmail());
return toAjax(1);
}
由於是測試功能,沒有在代碼結構上下功夫,隨便寫一下。主要的代碼是王模板上下文Context中填充參數,engine.process()有很多重載的方法,主要有兩類,一類是直接輸出內容,一類是將文件輸出到指定文件里。String template 這個參數指的是模板的名稱。比如我的叫mailTeamlate,解析的時候模板引擎會找classpath:templates/mailTeamlate.html 這個文件。
public final String process(String template, IContext context) { return this.process(new TemplateSpec(template, (Set)null, (TemplateMode)null, (String)null, (Map)null), context); }
public final void process(String template, IContext context, Writer writer) { this.process(new TemplateSpec(template, (Set)null, (TemplateMode)null, (String)null, (Map)null), context, writer); }
4.效果
具體的文件內容就不說了,直接看我放到郵件的里面正文里的html樣式

