最近项目里要做一个根据客户提供的word模板导出word的功能,方法有很多,比如easyPoi(对word的支持并不是很好),freeMark(太麻烦不想研究),以及poi-tl,
最后研究了半天发现也就只有poi-tl比较符合我的需求,特意记录下以防日后用到忘记了。
这是想要的word结果
这是我的word模板
代码如下:
try {
DecimalFormat df = new DecimalFormat("###################.###########");
SettlementResponse.All settlement = getDetails(settlementId);
Map<String, Object> params = new HashMap<>();
params.put("guestName", settlement.getBase().getGuestName());
String visitStart = DateUtil.timestamp2String(settlement.getBase().getVisitTimeStart(),"yyyy年MM月dd日");
String visitEnd = DateUtil.timestamp2String(settlement.getBase().getVisitTimeStart(),"MM月dd日");
params.put("visitDate", visitStart+ "-" + visitEnd);
SettlementResponse.Detail detail = settlement.getDetail();
double total = 0;
//住宿费列表
if (MyUtil.isNotBlank(detail.getAccomResponse())){
SettlementAccomResponse accomResponse = detail.getAccomResponse();
Map<String,Object> accomMap = getAccomdation(accomResponse);
params.put("accomList", accomMap.get("accomList"));
params.put("accomOwn", accomMap.get("accomOwn"));
params.put("accomTotal", accomMap.get("accomTotal"));
total = total + accomResponse.getSubtotal().doubleValue();
}
//会场费列表
List<Map<String,Object>> meetList = new ArrayList<>();
if (CollectionUtil.isNotEmpty(detail.getMeetingResponseList())){
Map<String,Object> meetingMap = getMeeting(detail.getMeetingResponseList());
params.put("meetList", meetingMap.get("meetList"));
params.put("meetTotal",meetingMap.get("meetTotal"));
total = total + Double.parseDouble(meetingMap.get("meetTotal").toString());
} else{
meetList.add(new HashMap<String, Object>() {{
put("meetTime", "");
put("meetPlace", "");
put("roomName", "");
put("meetCost", "");
}});
params.put("meetList",meetList);
}
//餐饮费列表
if (MyUtil.isNotBlank(detail.getMealsResponse())){
List<SettlementMealsResponse.MealsDetail> mealsDetailList = detail.getMealsResponse().getMealsDetailList();
Map<String,Object> mealsMap = getMeals(mealsDetailList);
params.put("workMeal", mealsMap.get("workMeal"));
params.put("dailMeal", mealsMap.get("dailMeal"));
params.put("otheMeal", mealsMap.get("otheMeal"));
params.put("mealsOwn", df.format(detail.getMealsResponse().getOwnExpense()));
params.put("mealTotal", df.format(detail.getMealsResponse().getSubtotal()));
total = total + detail.getMealsResponse().getSubtotal().doubleValue();
}
//其他费用列表
List<Map<String,Object>> otherList = new ArrayList<Map<String,Object>>();
if (CollectionUtil.isNotEmpty(detail.getOthersList())){
Map<String,Object> otherMap = getOther(detail.getOthersList());
params.put("otherList", otherMap.get("otherList"));
params.put("otherTotal", otherMap.get("otherTotal"));
total = total + Double.parseDouble(otherMap.get("otherTotal").toString());
}else{
otherList.add(new HashMap<String, Object>() {{
put("otherRemark", "");
put("otherCost", "");
}});
params.put("otherList", otherList);
}
//文印费
params.put("printRemark", detail.getPrints().getDescription());
params.put("printTotal", df.format(detail.getPrints().getCost()));
total = total + detail.getPrints().getCost().doubleValue();
params.put("total", df.format(total));
//word模板地址,如果项目需要部署在linux环境中,需要以流的方式读取文件否则会读取不到
InputStream resource= this.getClass().getClassLoader().getResourceAsStream("static/template/settlement.docx");
//渲染表格,new HackLoopTableRenderPolicy(true)即模板标签和循环行在同一行而不是在上一行
HackLoopTableRenderPolicy policy = new HackLoopTableRenderPolicy(true);
Configure config = Configure.builder()
.bind("accomList", policy)
.bind("meetList", policy)
.bind("workMeal", policy)
.bind("dailMeal", policy)
.bind("otheMeal", policy)
.bind("otherList", policy)
.build();
XWPFTemplate template = XWPFTemplate.compile(resource, config).render(params);
String fileName = "接待任务费用结算表" + "-" + System.currentTimeMillis();
ExportWordUtils.downloadWord(response, fileName, template);
} catch (Exception e) {
e.printStackTrace();
}
public class ExportWordUtils {
/**
* 根据模板填充内容生成word,并下载
* @param templatePath word模板文件路径
* @param paramMap 替换的参数集合
*/
public static void compileWord(HttpServletResponse response, InputStream templatePath, Map<String, Object> paramMap, String fileName) throws UnsupportedEncodingException {
// 读取模板templatePath并将paramMap的内容填充进模板,即编辑模板(compile)+渲染数据(render)
XWPFTemplate template = XWPFTemplate.compile(templatePath).render(paramMap);
downloadWord(response, fileName, template);
}
public static void downloadWord(HttpServletResponse response, String fileName, XWPFTemplate template) throws UnsupportedEncodingException {
response.setContentType("application/octet-stream");
fileName = URLEncoder.encode(fileName, "UTF-8");
response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".docx");
//设置生成的文件临时存放路径
String rootPath="./wordTemplate";
String filePath = rootPath + fileName;
File newFile = new File(filePath);
if(!newFile.getParentFile().exists()){
newFile.getParentFile().mkdirs();
}
try {
OutputStream out = response.getOutputStream();
// 将填充之后的模板写入filePath
template.write(out);
out.flush();
out.close();
template.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
最后附上poi-tl的文档地址: http://deepoove.com/poi-tl/#hack-loop-table
版权声明:本文为CobainXu原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。