FreeMarker 是一款 模板引擎: 即一种基于模板和要改变的数据, 并用来生成输出文本(HTML网页,电子邮件,配置文件,源代码等)的通用工具。 它不是面向最终用户的,而是一个Java类库,是一款程序员可以嵌入他们所开发产品的组件。
静态页面生成的代码
// 第一步:创建一个Configuration对象,直接new一个对象。构造方法的参数就是freemarker对于的版本号。
Configuration configuration = new Configuration(Configuration.getVersion());
// 第二步:设置模板文件所在的路径。
configuration.setDirectoryForTemplateLoading(new File("路径"));
// 第三步:设置模板文件使用的字符集。一般就是utf-8.
configuration.setDefaultEncoding("utf-8");
// 第四步:加载一个模板,创建一个模板对象。
Template template = configuration.getTemplate("test.ftl");
// 第五步:创建一个模板使用的数据集,可以是pojo也可以是map。一般是Map。
Map dataModel = new HashMap<>();
//向数据集中添加数据
dataModel.put("hello", "ABCD");
// 第六步:创建一个Writer对象,一般创建一FileWriter对象,指定生成的文件名。
Writer out = new FileWriter(new File("E:\\IDEA-tuling\\Item4\\test.html"));
// 第七步:调用模板对象的process方法输出文件。
template.process(dataModel, out);
// 第八步:关闭流。
out.close();
当前文件目录下 classpath: xxx.jsp
如果ftl是个string字符串
//读取文件内容变成string字符串
FileReader fileReader = null;
String filePath = "E:\\A\\Item4\\使用说明.txt";
try {
int readData ;
fileReader = new FileReader(filePath);
while ((readData = fileReader.read())!= -1) {
System.out.print((char)readData);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(fileReader!=null){
fileReader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
String ftl= "";//模板内容 上述解析的文件字符串
StringTemplateLoader stringTemplateLoader = new StringTemplateLoader();
stringTemplateLoader.putTemplate("a.ftl",ftl);
configuration.setTemplateLoader(stringTemplateLoader);
如果最后也是返回一个String字符串为文件内容,而不是返回String路径
// 方法一:使用 Configuration.getTemplate() 方法
// 使用 Template.process() 方法
String jspTemplate = create();
Configuration configuration = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
configuration.setDefaultEncoding("UTF-8");
// 创建一个 StringTemplateLoader
StringTemplateLoader templateLoader = new StringTemplateLoader();
// 将 JSP 模板添加到 StringTemplateLoader 中
templateLoader.putTemplate("A.ftl",jspTemplate);
// 设置配置对象的模板加载器为 StringTemplateLoader
configuration.setTemplateLoader(templateLoader);
// 加载模板
Template template = configuration.getTemplate("A.ftl");
// 创建数据模型
Map<String, Object> dataModel = new HashMap<>();
dataModel.put("data", getData());//list集合
dataModel.put("div1", "A");
// 使用 StringWriter 来保存生成的静态页面内容
StringWriter writer = new StringWriter();
// 填充模板数据并生成页面内容
try {
// Template template = new Template("MyTemplate", new StringReader(jspTemplate), configuration);
template.process(dataModel, writer);
} catch (Exception e) {
e.printStackTrace();
}
// 获取生成的静态页面内容
String staticPageContent = writer.toString();
或
public static void main(String[] args) throws Exception {
Configuration configuration = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
configuration.setDefaultEncoding("UTF-8");
// 模拟 JSP 模板内容
String jspTemplate = "<table>\n" +
" <thead>\n" +
" <tr>\n" +
" <th>Column 1</th>\n" +
" <th>Column 2</th>\n" +
" </tr>\n" +
" </thead>\n" +
" <tbody>\n" +
" <#list data as item>\n" +
" <tr>\n" +
" <td>${item.column1}</td>\n" +
" <td>${item.column2}</td>\n" +
" </tr>\n" +
" </#list>\n" +
" </tbody>\n" +
"</table>";
// 创建数据模型
Map<String, Object> dataModel = new HashMap<>();
dataModel.put("data", getData());
// 使用 StringWriter 来保存生成的静态页面内容
StringWriter writer = new StringWriter();
// 填充模板数据并生成页面内容
try {
Template template = new Template("MyTemplate", new StringReader(jspTemplate), configuration);
template.process(dataModel, writer);
} catch (Exception e) {
e.printStackTrace();
}
// 获取生成的静态页面内容
String staticPageContent = writer.toString();
System.out.println(staticPageContent);
}
private static List<Map<String, String>> getData() {
List<Map<String, String>> data = new ArrayList<>();
Map<String, String> item1 = new HashMap<>();
item1.put("column1", "Data 1");
item1.put("column2", "Value 1");
data.add(item1);
Map<String, String> item2 = new HashMap<>();
item2.put("column1", "Data 2");
item2.put("column2", "Value 2");
data.add(item2);
return data;
}
// 方法二:使用 SpringTemplateEngine.process() 方法
ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver();
templateResolver.setTemplateMode(TemplateMode.HTML);
templateResolver.setPrefix("/templates/");
templateResolver.setSuffix(".ftl");
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver);
Map<String, Object> dataModel = new HashMap<>();
dataModel.put("name", "world");
Resource resource = templateEngine.process("myTemplate", new Context(Locale.getDefault(), dataModel));
String result = resource.toString();
html生成页面
yaml
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.12.1</version>
</dependency>
方式
public static void main(String[] args) {
String html = "<div id='div1'>aaa</div>" +
"<table id='table'>" +
" <tr>" +
" <th>列标题1</th>" +
" <th>列标题2</th>" +
" <th>列标题3</th>" +
" </tr>" +
" <tr>" +
" <td>行1,列1</td>" +
" <td>行1,列2</td>" +
" <td>行1,列3</td>" +
" </tr>" +
" <tr>" +
" <td>行2,列1</td>" +
" <td>行2,列2</td>" +
" <td>行2,列3</td>" +
" </tr>" +
"</table>";
Map<String, Object> map = new HashMap<>();
map.put("div1", "asd");
List<B> list = new ArrayList<>();
list.add(new B("a", "A", "Aa"));
list.add(new B("b", "B", "Bb"));
list.add(new B("c", "C", "Cc"));
map.put("table", list);
Document document = Jsoup.parse(html);
if (map != null && !map.isEmpty()) {
for (String key : map.keySet()) {
Element element = document.getElementById(key);
if (element != null) {
Object value = map.get(key);
if (element.tagName().equalsIgnoreCase("table")) {
processTableElement(element, value);
} else {
element.html(value.toString());
}
}
}
}
System.out.println(document.toString());
}
private static void processTableElement(Element element, Object value) {
if (value instanceof List) {
List<?> dataList = (List<?>) value;
if (!dataList.isEmpty()) {
Element theadElement = element.selectFirst("thead");
Element tr = null;
if (theadElement == null) {
tr = element.selectFirst("tr");
element.html("");
theadElement = element.appendElement("thead");
theadElement.html(tr.toString());
}
Element tbodyElement = element.selectFirst("tbody");
if (tbodyElement == null) {
tbodyElement = element.appendElement("tbody");
}
tbodyElement.html("");
for (Object item : dataList) {
Element trElement = tbodyElement.appendElement("tr");
processTableRowElement(trElement, item, false);
}
}
}
}
private static void processTableRowElement(Element element, Object item, boolean isHeaderRow) {
Field[] fields = item.getClass().getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
try {
Object fieldValue = field.get(item);
Element tdElement = element.appendElement(isHeaderRow ? "th" : "td");
tdElement.text(fieldValue != null ? fieldValue.toString() : "");
} catch (IllegalAccessException e) {
e.printStackTrace();
}
field.setAccessible(false);
}
}
策略模式优化 大致思路
// 合同生成接口
public interface ContractGenerator {
void generateContract();
}
// JSP 模式合同生成器
public class JspContractGenerator implements ContractGenerator {
@Override
public void generateContract() {
// 在此处编写 JSP 模式的合同生成逻辑
System.out.println("生成 JSP 模式的合同");
}
}
// HTML 模式合同生成器
public class HtmlContractGenerator implements ContractGenerator {
@Override
public void generateContract() {
// 在此处编写 HTML 模式的合同生成逻辑
System.out.println("生成 HTML 模式的合同");
}
}
// 合同生成器工厂
public class ContractGeneratorFactory {
private static final Map<String, Supplier<ContractGenerator>> CONTRACT_GENERATORS = new HashMap<>();
static {
CONTRACT_GENERATORS.put("jsp", JspContractGenerator::new);
CONTRACT_GENERATORS.put("html", HtmlContractGenerator::new);
}
public static ContractGenerator createContractGenerator(String type) {
Supplier<ContractGenerator> generatorSupplier = CONTRACT_GENERATORS.get(type.toLowerCase());
if (generatorSupplier == null) {
throw new IllegalArgumentException("不支持的合同类型:" + type);
}
return generatorSupplier.get();
}
}
// 使用策略模式生成合同
public class ContractApp {
public static void main(String[] args) {
String contractType = "jsp"; // 或者 "html"
ContractGenerator contractGenerator = ContractGeneratorFactory.createContractGenerator(contractType);
contractGenerator.generateContract();
}
}
其他方式
String inStr = "尊敬的${name}你好,你今年芳龄${age},你的工作内容是${job}";
String pattern = "\\$\\{\\w+}";
Matcher matcher = Pattern.compile(pattern).matcher(inStr);
Map<String,String> argsContext = new HashMap<>();
argsContext.put("name","a");
argsContext.put("age","25");
argsContext.put("job","ptam");
while (matcher.find()){
String arg = matcher.group();
String subArgs = arg.substring(2,arg.length()-1);
inStr = inStr.replace(arg,argsContext.get(subArgs));
多条列表的效果
List< ? extends Map<String,String> > listMap = new ArrayList<>(){
{
add(new HashMap<>(){
{
put("name","小明");
put("age","25");
put("job" ,"java");
}
});
add(new HashMap<>(){
{
put("name","小亮");
put("age","25");
put("job","C++");
}
});
add(new HashMap<>(){
{
put("name","小红");
put("age","25");
put("job" ,"python");
}
});
}
};
for (Map<String,String> map:listMap){
String pattern = "\\$\\{\\w+}";
String inStr = "尊敬的${name}你好,你今年芳龄${age},你的工作内容是${job}";
Matcher matcher = Pattern.compile(pattern).matcher(inStr);
while (matcher.find(){
String arg = matcher.group();
String subArgs = arg.substring(2,arg.length(-1);
inStr = inStr.replace(arg,map.get(subArgs));
}
System.out.println(inStr);