diff --git a/src/main/java/xyz/wbsite/dbtool/javafx/manger/callable/SpringBootCallable.java b/src/main/java/xyz/wbsite/dbtool/javafx/manger/callable/SpringBootCallable.java
index 72d8bca9..13932bcd 100644
--- a/src/main/java/xyz/wbsite/dbtool/javafx/manger/callable/SpringBootCallable.java
+++ b/src/main/java/xyz/wbsite/dbtool/javafx/manger/callable/SpringBootCallable.java
@@ -693,10 +693,12 @@ public class SpringBootCallable implements Callable {
             ctx.put("domain", project.getDomain());
             ctx.put("moduleName", project.getName());
             ctx.put("author", project.getAuthor());
-            File file = Tool.createFile(root, "UtilTest" + ".java");
-            freeMarkerManager.outputTemp(file, "SpringBoot/test/UtilTest.java", ctx);
-            freeMarkerManager.outputTemp(Tool.createFile(root, "ExcelTest.java"), "SpringBoot/test/ExcelTest.java", ctx);
-            freeMarkerManager.outputTemp(Tool.createFile(root, "MailTest.java"), "SpringBoot/test/MailTest.java", ctx);
+            File frame = Tool.createPath(root, "frame");
+            freeMarkerManager.outputTemp(Tool.createFile(frame, "ExcelTest.java"), "SpringBoot/test/frame/ExcelTest.java", ctx);
+            if (project.isNeedEMail()){
+                freeMarkerManager.outputTemp(Tool.createFile(frame, "MailTest.java"), "SpringBoot/test/frame/MailTest.java", ctx);
+            }
+            freeMarkerManager.outputTemp(Tool.createFile(frame, "UtilTest.java"), "SpringBoot/test/frame/UtilTest.java", ctx);
         }
 
         for (Module md : project.getModules()) {
diff --git a/src/main/resources/modules/SpringBoot/java/frame/mail/WMailSender.java b/src/main/resources/modules/SpringBoot/java/frame/mail/WMailSender.java
index ed822817..84b66c99 100644
--- a/src/main/resources/modules/SpringBoot/java/frame/mail/WMailSender.java
+++ b/src/main/resources/modules/SpringBoot/java/frame/mail/WMailSender.java
@@ -36,7 +36,7 @@ public class WMailSender {
             helper.setFrom(message.getFrom());
             helper.setTo(message.getTo());
             helper.setSubject(message.getSubject());
-            helper.setText(message.getContent());
+            helper.setText(message.getContent(), true);
             sender.send(mimeMessage);
         } catch (MessagingException e) {
             e.printStackTrace();
@@ -52,7 +52,7 @@ public class WMailSender {
             helper.setFrom(message.getFrom());
             helper.setTo(message.getTo());
             helper.setSubject(message.getSubject());
-            helper.setText(message.getContent(), true);
+            helper.setText(message.getContent());
             sender.send(mimeMessage);
         } catch (MessagingException e) {
             e.printStackTrace();
@@ -64,7 +64,7 @@ public class WMailSender {
     private static boolean send(WFileMessage message, JavaMailSender sender) {
         try {
             MimeMessage mimeMessage = sender.createMimeMessage();
-            MimeMessageHelper helper = new MimeMessageHelper(mimeMessage);
+            MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
             helper.setFrom(message.getFrom());
             helper.setTo(message.getTo());
             helper.setSubject(message.getSubject());
@@ -85,7 +85,7 @@ public class WMailSender {
     private static boolean send(WInlineMessage message, JavaMailSender sender) {
         try {
             MimeMessage mimeMessage = sender.createMimeMessage();
-            MimeMessageHelper helper = new MimeMessageHelper(mimeMessage);
+            MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
             helper.setFrom(message.getFrom());
             helper.setTo(message.getTo());
             helper.setSubject(message.getSubject());
@@ -131,14 +131,14 @@ public class WMailSender {
         if (message.getFrom() == null && sender instanceof JavaMailSenderImpl) {
             message.setFrom(((JavaMailSenderImpl) sender).getUsername());
         }
-        if (message instanceof WTextMessage) {
-            return send((WTextMessage) message, sender);
-        } else if (message instanceof WHtmlMessage) {
-            return send((WHtmlMessage) message, sender);
-        } else if (message instanceof WFileMessage) {
+        if (message instanceof WFileMessage) {
             return send((WFileMessage) message, sender);
         } else if (message instanceof WInlineMessage) {
             return send((WInlineMessage) message, sender);
+        } else if (message instanceof WHtmlMessage) {
+            return send((WHtmlMessage) message, sender);
+        } else if (message instanceof WTextMessage) {
+            return send((WTextMessage) message, sender);
         } else {
             throw new RuntimeException("Unimplemented message type!");
         }
diff --git a/src/main/resources/modules/SpringBoot/java/frame/utils/FreeMarkerUtil.java b/src/main/resources/modules/SpringBoot/java/frame/utils/FreeMarkerUtil.java
index c69836a7..bef49dec 100644
--- a/src/main/resources/modules/SpringBoot/java/frame/utils/FreeMarkerUtil.java
+++ b/src/main/resources/modules/SpringBoot/java/frame/utils/FreeMarkerUtil.java
@@ -8,8 +8,7 @@ import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;
 
 import java.io.File;
 import java.io.IOException;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
+import java.io.StringWriter;
 import java.io.Writer;
 
 public class FreeMarkerUtil {
@@ -63,18 +62,16 @@ public class FreeMarkerUtil {
     /**
      * 通过模板渲染
      *
-     * @param template     模板
-     * @param outputStream 输出流
-     * @param model        数据模型
+     * @param template 模板
+     * @param model    数据模型
+     * @param writer   字符输出流
      */
-    public static boolean render(Template template, OutputStream outputStream, Object model) {
+    public static boolean render(Template template, Object model, Writer writer) {
         try {
-            // 创建字符流
-            Writer wr = new OutputStreamWriter(outputStream, "UTF-8");
             // 渲染
-            template.process(model, wr);
+            template.process(model, writer);
             // 关闭流
-            wr.close();
+            writer.close();
             return true;
         } catch (IOException | TemplateException e) {
             e.printStackTrace();
@@ -85,70 +82,127 @@ public class FreeMarkerUtil {
     /**
      * 通过模板资源渲染
      *
-     * @param resources    模板资源
-     * @param outputStream 输出流
-     * @param model        数据模型
-     */
-    public static boolean renderByResources(String resources, OutputStream outputStream, Object model) {
-        return renderByResources(resources, true, outputStream, model);
-    }
-
-    /**
-     * 通过模板资源渲染
-     *
-     * @param resources            模板资源
      * @param defaultConfiguration 是否使用默认配置,与视图模板同目录同配置
-     * @param outputStream         输出流
+     * @param resources            模板资源
      * @param model                数据模型
+     * @param writer               字符输出流
      */
-    public static boolean renderByResources(String resources, boolean defaultConfiguration, OutputStream outputStream, Object model) {
+    public static boolean renderByResources(boolean defaultConfiguration, String resources, Object model, Writer writer) {
         Configuration newConfiguration = defaultConfiguration ? getDefaultConfiguration() : getNewConfiguration();
         try {
             // 构建模板
             Template template = newConfiguration.getTemplate(resources);
             // 渲染模板
-            return render(template, outputStream, model);
+            return render(template, model, writer);
         } catch (IOException e) {
             e.printStackTrace();
             return false;
         }
     }
 
+    /**
+     * 通过模板资源渲染
+     *
+     * @param defaultConfiguration 是否使用默认配置,与视图模板同目录同配置
+     * @param resources            模板资源
+     * @param model                数据模型
+     * @return 渲染结果字符串
+     */
+    public static String renderByResources(boolean defaultConfiguration, String resources, Object model) {
+        StringWriter writer = new StringWriter();
+        boolean b = renderByResources(defaultConfiguration, resources, model, writer);
+        if (!b) return "";
+        return writer.toString();
+    }
+
+    /**
+     * 通过模板资源渲染
+     *
+     * @param resources 模板资源
+     * @param model     数据模型
+     * @param writer    字符输出流
+     */
+    public static boolean renderByResources(String resources, Object model, Writer writer) {
+        return renderByResources(true, resources, model, writer);
+    }
+
+    /**
+     * 通过模板资源渲染
+     *
+     * @param resources 模板资源
+     * @param model     数据模型
+     * @return 渲染结果字符串
+     */
+    public static String renderByResources(String resources, Object model) {
+        StringWriter writer = new StringWriter();
+        boolean b = renderByResources(true, resources, model, writer);
+        if (!b) return "";
+        return writer.toString();
+    }
+
     /**
      * 通过模板文件渲染
      *
-     * @param file         模板文件
-     * @param outputStream 输出流
-     * @param model        数据模型
+     * @param file   模板文件
+     * @param model  数据模型
+     * @param writer 字符输出流
      */
-    public static boolean renderByFile(File file, OutputStream outputStream, Object model) {
+    public static boolean renderByFile(File file, Object model, Writer writer) {
         try {
             // 构建模板
             Template template = new Template(file.getName(), FileUtil.readFileToString(file), getDefaultConfiguration());
             // 渲染模板
-            return render(template, outputStream, model);
+            return render(template, model, writer);
         } catch (IOException e) {
             e.printStackTrace();
             return false;
         }
     }
 
+    /**
+     * 通过模板文件渲染
+     *
+     * @param file  模板文件
+     * @param model 数据模型
+     * @return 渲染结果字符串
+     */
+    public static String renderByFile(File file, Object model) {
+        StringWriter writer = new StringWriter();
+        boolean b = renderByFile(file, model, writer);
+        if (!b) return "";
+        return writer.toString();
+    }
+
     /**
      * 通过模板字符串渲染
      *
-     * @param source       模板字符串
-     * @param outputStream 输出流
-     * @param model        数据模型
+     * @param source 模板字符串
+     * @param model  数据模型
+     * @param writer 字符输出流
      */
-    public static boolean renderByString(String source, OutputStream outputStream, Object model) {
+    public static boolean renderByString(String source, Object model, Writer writer) {
         try {
             // 构建模板
             Template template = new Template(MD5Util.encode(source), source, getDefaultConfiguration());
             // 渲染模板
-            return render(template, outputStream, model);
+            return render(template, model, writer);
         } catch (IOException e) {
             e.printStackTrace();
             return false;
         }
     }
+
+    /**
+     * 通过模板字符串渲染
+     *
+     * @param source 模板字符串
+     * @param model  数据模型
+     * @return 渲染结果字符串
+     */
+    public static String renderByString(String source, Object model) {
+        StringWriter writer = new StringWriter();
+        boolean b = renderByString(source, model, writer);
+        if (!b) return "";
+        return writer.toString();
+    }
 }
diff --git a/src/main/resources/modules/SpringBoot/test/MailTest.java b/src/main/resources/modules/SpringBoot/test/MailTest.java
deleted file mode 100644
index eeb339a5..00000000
--- a/src/main/resources/modules/SpringBoot/test/MailTest.java
+++ /dev/null
@@ -1,35 +0,0 @@
-package com.example;
-
-import com.example.frame.mail.WMailSender;
-import com.example.frame.mail.message.WHtmlInlineMessage;
-import com.example.frame.mail.message.WTextMessage;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.test.context.junit4.SpringRunner;
-import org.springframework.transaction.annotation.Transactional;
-
-import java.io.File;
-
-/**
- * UtilTest -  - 测试用例
- *
- * @author wangbing
- * @version 0.0.1
- * @since 2017-01-01
- */
-@RunWith(SpringRunner.class)
-@SpringBootTest
-@Transactional
-public class MailTest {
-
-    @Test
-    public void testGeneratePwd() {
-        WTextMessage message = new WTextMessage();
-        message.setSubject("测试");
-        message.setContent("测试");
-        message.setFrom("wangbing@wbsite.xyz");
-        message.setTo("1919101440@qq.com");
-        WMailSender.send(message);
-    }
-}
diff --git a/src/main/resources/modules/SpringBoot/test/ExcelTest.java b/src/main/resources/modules/SpringBoot/test/frame/ExcelTest.java
similarity index 99%
rename from src/main/resources/modules/SpringBoot/test/ExcelTest.java
rename to src/main/resources/modules/SpringBoot/test/frame/ExcelTest.java
index 62374087..6e15345a 100644
--- a/src/main/resources/modules/SpringBoot/test/ExcelTest.java
+++ b/src/main/resources/modules/SpringBoot/test/frame/ExcelTest.java
@@ -1,4 +1,4 @@
-package ${domain};
+package ${domain}.frame;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
diff --git a/src/main/resources/modules/SpringBoot/test/frame/MailTest.java b/src/main/resources/modules/SpringBoot/test/frame/MailTest.java
new file mode 100644
index 00000000..cf0504f6
--- /dev/null
+++ b/src/main/resources/modules/SpringBoot/test/frame/MailTest.java
@@ -0,0 +1,65 @@
+package ${domain}.frame;
+
+import ${domain}.frame.mail.WMailSender;
+import ${domain}.frame.mail.message.WFileMessage;
+import ${domain}.frame.mail.message.WHtmlMessage;
+import ${domain}.frame.mail.message.WInlineMessage;
+import ${domain}.frame.mail.message.WTextMessage;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.io.File;
+
+/**
+ * UtilTest -  - 测试用例
+ *
+ * @author wangbing
+ * @version 0.0.1
+ * @since 2017-01-01
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest
+@Transactional
+public class MailTest {
+
+    @Test
+    public void testTextMessage() {
+        WTextMessage message = new WTextMessage();
+        message.setSubject("测试(文本)");
+        message.setContent("文本内容");
+        message.setTo("1919101440@qq.com");
+        WMailSender.send(message);
+    }
+
+    @Test
+    public void testHtmlMessage() {
+        WHtmlMessage message = new WHtmlMessage();
+        message.setSubject("测试(HTML)");
+        message.setContent("<a href='https://www.baidu.com'>百度一下</a>");
+        message.setTo("1919101440@qq.com");
+        WMailSender.send(message);
+    }
+
+    @Test
+    public void testFileMessage() {
+        WFileMessage message = new WFileMessage();
+        message.setSubject("测试(附件)");
+        message.setContent("请参考附件。");
+        message.setTo("1919101440@qq.com");
+        message.addFile(new File("E:\\A.xlsx"));
+        WMailSender.send(message);
+    }
+
+    @Test
+    public void testInlineMessage() {
+        WInlineMessage message = new WInlineMessage();
+        message.setSubject("测试(图片)");
+        message.setContent("<img src='cid:resId_1'></img>");
+        message.setTo("1919101440@qq.com");
+        message.addRes("resId_1", new File("E:\\1.jpg"));
+        WMailSender.send(message);
+    }
+}
diff --git a/src/main/resources/modules/SpringBoot/test/UtilTest.java b/src/main/resources/modules/SpringBoot/test/frame/UtilTest.java
similarity index 89%
rename from src/main/resources/modules/SpringBoot/test/UtilTest.java
rename to src/main/resources/modules/SpringBoot/test/frame/UtilTest.java
index 2d5b9b86..3e8fd16d 100644
--- a/src/main/resources/modules/SpringBoot/test/UtilTest.java
+++ b/src/main/resources/modules/SpringBoot/test/frame/UtilTest.java
@@ -1,25 +1,21 @@
-package ${domain};
+package ${domain}.frame;
 
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.test.context.junit4.SpringRunner;
-import org.springframework.transaction.annotation.Transactional;
 import ${domain}.frame.utils.AESUtil;
 import ${domain}.frame.utils.Base64Util;
+import ${domain}.frame.utils.FreeMarkerUtil;
 import ${domain}.frame.utils.IDgenerator;
 import ${domain}.frame.utils.MD5Util;
 import ${domain}.frame.utils.ProcessUtil;
 import ${domain}.frame.utils.RSAUtil;
 import ${domain}.frame.utils.ZipUtil;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+import org.springframework.transaction.annotation.Transactional;
 
 import java.io.File;
-import java.io.IOException;
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Date;
-import java.util.List;
+import java.util.HashMap;
 
 /**
  * UtilTest -  - 测试用例
@@ -113,4 +109,13 @@ public class UtilTest {
         //压缩
         ZipUtil.toZip(new File("E:\\AAA"), new File("E:\\AAA.zip"));
     }
+
+    @Test
+    public void testFreeMarker() {
+        HashMap<String, String> data = new HashMap<>();
+        data.put("msg", "你好!");
+
+        String string = FreeMarkerUtil.renderByString("==${r'${msg}'}==", data);
+        System.out.println(string);
+    }
 }