最近项目里要做一个根据客户提供的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();// 将填充之后的模板写入filePathtemplate.write(out);out.flush();out.close();template.close();} catch (Exception e) {e.printStackTrace();}}
}

最后附上poi-tl的文档地址: http://deepoove.com/poi-tl/#hack-loop-table

poi-tl,根据word模板导出word(表格行循环,表格无表头的情况)相关推荐

  1. Springboot--使用POI,根据word模板导出word文件

    需求:根据一个word模板,在程序中替换模板中的参数,然后根据这个模板导出word文件. 引入POI对word操作的依赖: <dependency><groupId>org.a ...

  2. java 导出word,java根据提供word模板导出word文档

    本文主要讲解,利用poi-tl在word中动态生成表格行,进行文字.图片填充.一共提供了两种方式,1.基于本地文件 2.基于网络文件 本文讲解思路,1.先看示例,2. 示例对应的代码展示 3. 基本概 ...

  3. 使用Word模板导出Word后,表格后面产生空白页

    目录 背景 解决 参考 背景 项目中有导出Word功能,其实现逻辑是先整理一个Word文档,里面使用占位符:代码读取Word文档,然后替换占位符. 但出现这样的问题:填充某个表格后,表格后面出现了空白 ...

  4. 用word模板导出word文档

    项目需求要把页面上的分析结果导出为word文档,实现的办法是POI.查了一下网上很多方式都采用FreeMark,自己认为比较麻烦,所以还是采取了POI导出.之前的框架是SSH的,现在换成了Spring ...

  5. 基于Easypoi+jfree,使用SpringBoot架构,Java编程实现word模板导出Word报表

    目录 1.项目目录结构 2.pom.xml添加的依赖 3.编写jfreeutil工具类 4.编写wordutil工具类 5.编写word模板 7.运行效果 8.复杂布局实现 8.1如何实现图片并排 S ...

  6. Aspose.Words利用Word模板导出Word文档

    今天工作中遇到了导出Word文档的问题,但是在搜索Aspose.Words 导出Word文档时发现网上的方法都是有头没尾的,有的只有一小段实例,让人看着摸不着头脑. 利用Aspose.Words导出W ...

  7. python连接小程序云开发数据库,并根据word模板导出word

    需求:微信小程序云开发数据库存储,需要将数据库中的答案进行导出,从而生成一个word 难点1: 利用python的docxtpl包进行模板导出 难点2: python获取云开发的数据库数据 难点3: ...

  8. java根据提供word模板导出word文档

    涉及主要jar包为 freemarker-2.3.10.jar,servlet-api-2.4.jar. (1)首先修改 word模板如下形式,把需要查询写入word的值用${}形式封装 (2)把 w ...

  9. Java使用word模板导出word

    1.创建一个空的springboot工程,引入jar包 <dependency><groupId>org.apache.poi</groupId><artif ...

最新文章

  1. linux下top命令
  2. java子程序_JAVA-JVM的执行子程序(类加载)
  3. java和c语言的区别_单片机为什么一直用C语言,不用其他编程语言?只有学过的知道...
  4. 计算机网络中的时延有哪几部分,计算机网络中的四种延迟分别是什么?
  5. GDCM:gdcm::Printer的测试程序
  6. updating error reports database解决方案
  7. 网页现现实理服务器没有响应,前端_网页编程 HTTP协议(进阶)
  8. android之修改gradle源
  9. 洛谷P4458 /loj#2512.[BJOI2018]链上二次求和(线段树)
  10. 设计不难学,这10款软件总有一款适合你
  11. Bugku-网站被黑
  12. xp系统如何更改计算机用户名,xp用administrator_XP系统修改administrator的用户名_xpadministrator...
  13. 在Linux Mint 19.2 XFCE(x64)中安装Canon LBP2900+打印机驱动程序
  14. 安徽省省二级c语言准考证号查询系统,网办进度考试查询系统
  15. jbox弹窗_jbox很好的弹出层 很好的弹出层 - 下载 - 搜珍网
  16. 腾讯音乐路演PPT曝光:发行区间13至15美元 下周上市
  17. 【3Dsmax】入门
  18. 微信小程序:音乐播放器带进度条
  19. Java8 Stream的用法
  20. FreeCAD软件安装

热门文章

  1. python计算负数的平方根将产生_pow(x,0.5)能够计算x的平方根,计算负数的平方根将产生:_学小易找答案...
  2. SAS/SATA/SSD/IDE硬盘介绍区别
  3. SOJ 4583 动态规划之分组背包
  4. 集合的基本操作和基本运算
  5. Python 网络爬虫实战:去哪儿网旅游攻略图文爬取保存为 Markdown电子书
  6. Notes of Python Cookbook (Chr1-Chr3)
  7. 调用有赞云api的前置工作——获取token
  8. Python编程——多进程与多线程编程(附实例)
  9. 【NOIP模拟赛】七夕祭(环形均分纸牌)
  10. 计算机产业八大难题待攻克