依赖:
<dependency>
<groupId>com.deepoovegroupId>
<artifactId>poi-tlartifactId>
<version>1.6.0version>
dependency>
工具类:
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.data.TextRenderData;
import com.deepoove.poi.data.style.Style;
import com.vxdata.activity.entity.CulturalActivity;
import com.vxdata.activity.entity.CulturalMaterial;
import com.vxdata.common.utils.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Component
public class PoiTlWordUtil {
/**
* 模板路径
*/
@Value("${word.templateUrl}")
private String templateUrl;
/**
* 实体生成Word
*
* @param culturalActivity 活动信息
*/
public void beanToWord(HttpServletResponse response, CulturalActivity culturalActivity) {
try {
Map<String, Object> map = getData(culturalActivity);
generateWord(response, templateUrl, map);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 替换模板中的字段
* 输出到本地路径中
*
* @param templateUrl 模板地址
* @param outUrl 输出word地址
* @param map 替换信息
* @throws IOException
*/
public static void generateWord(String templateUrl, String outUrl, Map<String, Object> map) throws IOException {
XWPFTemplate render = XWPFTemplate.compile(templateUrl).render(map);
render.writeToFile(outUrl);
}
/**
* 替换模板中的字段
* 直接响应前端
*
* @param response 前端响应
* @param templateUrl 模板路径
* @param map 替换信息
* @throws IOException
*/
public static void generateWord(HttpServletResponse response, String templateUrl, Map<String, Object> map) throws IOException {
XWPFTemplate render = XWPFTemplate.compile(templateUrl).render(map);
render.write(response.getOutputStream());
}
/**
* 根据活动信息构建word需要的map
*
* @param activity 活动信息
* @return
*/
public static Map<String, Object> getData(CulturalActivity activity) {
Map<String, Object> map = new HashMap<>();
// 时间
DateTimeFormatter dfDate = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
map.put("date", dfDate.format(activity.getHoldTime()));
// 地点
map.put("place", activity.getActivityAddr() == null ? "" : activity.getActivityRecord());
// 活动类别
map.put("type", activity.getActivityType() == null ? "" : activity.getActivityType());
// 人次
map.put("number", activity.getPeopleNumber() == null ? "" : activity.getPeopleNumber().toString());
// 主题
map.put("name", activity.getActivityName() == null ? "" : activity.getActivityName());
// 活动记录
map.put("record", activity.getActivityRecord() == null ? "" : activity.getActivityRecord());
// 使用 Wingdings 2 字体来生成复选框, \u00A : 不选中 , R : 选中
// 复选框, 材料清单, 先规定全部是 □
map.put("0", new TextRenderData("\u00A3", new Style("Wingdings 2", 14)));
map.put("1", new TextRenderData("\u00A3", new Style("Wingdings 2", 14)));
map.put("2", new TextRenderData("\u00A3", new Style("Wingdings 2", 14)));
map.put("3", new TextRenderData("\u00A3", new Style("Wingdings 2", 14)));
map.put("4", new TextRenderData("\u00A3", new Style("Wingdings 2", 14)));
map.put("5", new TextRenderData("\u00A3", new Style("Wingdings 2", 14)));
map.put("6", new TextRenderData("\u00A3", new Style("Wingdings 2", 14)));
map.put("7", new TextRenderData("\u00A3", new Style("Wingdings 2", 14)));
map.put("8", new TextRenderData("\u00A3", new Style("Wingdings 2", 14)));
List<CulturalMaterial> materialList = activity.getCulturalMaterialList();
if (materialList != null && materialList.size() > 0) {
for (CulturalMaterial material : materialList) {
// 如果有这个类型的材料就 改成 对钩
if (StringUtils.isNotEmpty(material.getType())) {
map.put(material.getType(), new TextRenderData("R", new Style("Wingdings 2", 14)));
}
}
}
return map;
}
public static void main(String[] args) throws IOException {
String templateUrl = "D:\\word\\poi-tl\\template.docx";
String outUrl = "D:\\word\\poi-tl\\out_template.docx";
CulturalActivity culturalActivity = new CulturalActivity();
culturalActivity.setActivityAddr("苏州市");
culturalActivity.setActivityName("案发带点");
culturalActivity.setActivityType("图书馆");
culturalActivity.setActivityRecord("飞极速地方his一定会UDAHFIUASDIY");
culturalActivity.setHoldTime(LocalDate.now());
culturalActivity.setPeopleNumber(100);
Map<String, Object> map = getData(culturalActivity);
generateWord(templateUrl, outUrl, map);
}
}
freemarker 需要将模板转成ftl格式
FreeMarker模板制作
依赖:
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-freemarkerartifactId>
dependency>
工具类:
package com.vxdata.activity.utils;
import com.vxdata.activity.entity.CulturalActivity;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import java.io.*;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
/**
* freemarker 根据模板生成word
*/
public class WordUtil {
// ftl模板目录
private String ftlUrl = "D:/";
// ftl模板名称
private String ftlName = "活动记录表.ftl";
// 输出doc文件目录
private String outUrl = "D:/";
// 输出文件名称
private String outFileName = "活动记录表.doc";
/**
* 获取word填充数据
*
* @param activity
* @return
*/
private static Map<String, String> getData(CulturalActivity activity) {
Map<String, String> map = new HashMap<>();
// 时间
DateTimeFormatter dfDate = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
map.put("date", dfDate.format(activity.getHoldTime()));
// 地点
map.put("place", activity.getActivityAddr() == null ? "" : activity.getActivityRecord());
// 类别
String activityType = activity.getActivityType();
map.put("type", activityType);
// 人次
map.put("number", activity.getPeopleNumber() == null ? "" : activity.getPeopleNumber().toString() );
// 主题
map.put("name", activity.getActivityName() == null ? "" : activity.getActivityName());
// 活动记录
map.put("record", activity.getActivityRecord() == null ? "" : activity.getActivityRecord());
// 活动照片
map.put("photo", "");
// 复选框
map.put("check", "true");
return map;
}
/**
* 根据模板生成word
*/
public void beanToWord(CulturalActivity culturalActivity) throws IOException, TemplateException {
Map<String, String> map = getData(culturalActivity);
//Configuration用于读取ftl文件
Configuration configuration = new Configuration();
configuration.setDefaultEncoding("utf-8");
/*以下是两种指定ftl文件所在目录路径的方式, 注意这两种方式都是
* 指定ftl文件所在目录的路径,而不是ftl文件的路径
*/
//指定路径的第一种方式(根据某个类的相对路径指定)
//configuration.setClassForTemplateLoading(this.getClass(),"");
//指定路径的第二种方式,我的路径是C:/a.ftl
configuration.setDirectoryForTemplateLoading(new File(ftlUrl));
String outFileUrl = outUrl + "/" + outFileName;
// 输出文档路径及名称
File outFile = new File(outFileUrl);
//以utf-8的编码读取ftl文件
Template template = configuration.getTemplate(ftlName,"utf-8");
Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), "utf-8"),10240);
template.process(map, out);
out.close();
System.out.println(outFileUrl);
}
public static void main(String[] args) {
CulturalActivity culturalActivity = new CulturalActivity();
culturalActivity.setActivityAddr("苏州市");
culturalActivity.setActivityName("案发带点");
culturalActivity.setActivityType("图书馆");
culturalActivity.setActivityRecord("飞极速地方his一定会复苏的合法化欧虎的方法还是的厚爱输掉首的还搜毒害宿厚度卡号的覅U爱上开党会if改吧死胡大哥是大法官胡SDAHFIUASDIY");
culturalActivity.setHoldTime(LocalDate.now());
culturalActivity.setPeopleNumber(100);
try {
WordUtil wordUtil = new WordUtil();
wordUtil.beanToWord(culturalActivity);
} catch (IOException e) {
e.printStackTrace();
} catch (TemplateException e) {
e.printStackTrace();
}
System.out.println("好了");
}
}
模板注意点:
复选框的使用: 需要使用if标签来判断是否选中, 使用Wingdings 2字体, F052表示选中, F0A3表示不选中
<#if check=="true">
<w:r wsp:rsidR="00C441CA">
<w:rPr>
<w:rFonts w:ascii="宋体" w:h-ansi="宋体" w:hint="fareast"/>
<wx:font wx:val="宋体"/>
<w:sz w:val="24"/>
w:rPr>
<w:sym w:font="Wingdings 2" w:char="F052"/>
w:r>
<#else>
<w:r wsp:rsidR="00C441CA">
<w:rPr>
<w:rFonts w:ascii="宋体" w:h-ansi="宋体" w:hint="fareast"/>
<wx:font wx:val="宋体"/>
<w:sz w:val="24"/>
w:rPr>
<w:sym w:font="Wingdings 2" w:char="F0A3"/>
w:r>
#if>