暑期在杭州实习了两个月,主要是使用vue+SpringMVC进行一个网页开发。
而在开发的过程中,也遇到了比较常见的文件导出问题–以固定格式将数据存储在word、excel等office文件格式中
在网上搜索了许多方法,了解到要导出word文件,其实办法由很多,如jacob,java2word,FreeMarker,Apatch POI等等。
本文采用的是Apatch POI中的一系列API,它可以操作基于MicroSoft OLE 2 Compound Document Format的各种格式文件,可以通过这些API在Java中读写Excel、Word等文件。原则意义上来讲,POI更适合excel文件格式的导出,格式固定且代码简单。

而在使用POI操作word文档时,比较麻烦的一点是.doc文件和.docx文件是不同的,也就是说,需要使用不同的API来操作.doc文件和.docx文件。

一、.doc文件:使用HWPFDocument

1)模板文件

新建word模板文件,并在word文件中设置【标签】。

  • 普通数据:一般标签以 ${变量名} 的格式命名,其中 $ 和 {} 一定是英文符号,如 ${project} , ${time}。注意标签名不要重复
  • 表格文件:由于表格数据是由多组相同格式的数据组成,在计算机语言中,及由数组组成。其与普通数据不同,无需设置标签,只需要在word文件中新建空白表格,并设置表头即可,系统可以根据相应单元格的位置对表格数据进行设置。

    模板文件编辑完成之后,记得将模板文件放在项目中。本项目放在了template文件夹中,当然,放在哪里,在代码中就要使用相应的路径来获取相应的模板文件。

2)文件导出

在第一步中已经使用 ${} 的格式对标签进行了设置,那么在代码中,我们只需要使用给相应的标签设置值即可。具体代码如下:

public boolean Export2GeotechnicalLayeringTable(Map<String, Object> map_data,ArrayList<Map<String, String>> list_data,String templatePath,OutputStream out) {boolean result = false;FileInputStream in = null;HWPFDocument document = null;try {in = new FileInputStream(templatePath);document = new HWPFDocument(in);Range range = document.getRange();range.replaceText("${project_id}", map_data.get("project_id").toString());  //range.replaceText("${project_name}", map_data.get("project_name").toString());  //range.replaceText("${depth}", map_data.get("depth").toString());  //range.replaceText("${hole_id}", map_data.get("hole_id").toString());  //range.replaceText("${hole_altitude}", map_data.get("hole_altitude").toString());  //range.replaceText("${hole_mileage}", map_data.get("hole_mileage").toString());  //range.replaceText("${endhole_depth}", map_data.get("endhole_depth").toString());  ////写入表格数据//遍历range范围内的table。TableIterator tableIter = new TableIterator(range);  Table table;  TableRow row;  while (tableIter.hasNext()) {  table = tableIter.next();int rowNum = table.numRows();  for (int i=0, j=2; i<list_data.size()&&j<rowNum; i++,j++) {  row = table.getRow(j); row.getCell(0).insertBefore(list_data.get(i).get("layer_id"));row.getCell(1).insertBefore(list_data.get(i).get("start_depth"));row.getCell(2).insertBefore(list_data.get(i).get("end_depth"));row.getCell(3).insertBefore(list_data.get(i).get("geotechnical_name"));row.getCell(4).insertBefore(list_data.get(i).get("geotechnical_description"));row.getCell(5).insertBefore(list_data.get(i).get("sample_id"));row.getCell(6).insertBefore(list_data.get(i).get("sample_depth"));}  }  document.write(out);out.close();}catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}return result;}

其中map_data中存储的是普通数据,而list_data中存储的是要生成word表格的数组数据。
由于代码都是较简单的java代码,这里不做解释。
代码封装好之后,进行单元测试:

public void testTestWord() throws FileNotFoundException {WordUtils wordUtils = new WordUtils();String templatePath = "D:\\Program Files\\eclipse\\.metadata\\.plugins\\org.eclipse.wst.server.core\\tmp0\\wtpwebapps\\ZJICInformationManagement\\"+"template/钻孔岩土分层表模板.doc";Map<String, Object> map_data = new HashMap<>();map_data.put("project_id", "2019.21");map_data.put("project_name", "ZJIC");map_data.put("depth", "10.22");map_data.put("hole_id", "ZKS12");map_data.put("hole_altitude", "100");map_data.put("hole_mileage", "23.21");map_data.put("endhole_depth", "43");ArrayList<Map<String, String>> list_data = new ArrayList<>();Map<String, String> temp = new HashMap<>();for(int i=0;i<10;i++){temp = new HashMap<>();temp.put("layer_id", i+"");temp.put("start_depth", "start_depth");temp.put("end_depth", "end_depth");temp.put("geotechnical_name", "geotechnical_name");temp.put("geotechnical_description", "geotechnical_description");temp.put("sample_id", "sample_id");temp.put("sample_depth", "sample_depth");list_data.add(temp);}File file = new File("d:\\word\\test.doc");FileOutputStream out = new FileOutputStream(file);wordUtils.Export2GeotechnicalLayeringTable(map_data, list_data, templatePath, out);}

最后生成的文件路径为:d:\word\test.doc。

二、.docx文件:使用XWPFDocument

遇到的巨大的坑!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
XWPFDocument比HWPFDocument灵活,但是在生成word文件过程中,对于普通的数据,前者与后者一样,同样通过设置标签来进行导出。但是操作标签的方式不同,XWPFDocument可以读取段落中的所有字符,然后通过XWPFRun(文本对象),使用正则表达式对文本中的标签进行提取,然后设置标签的值…但是在获取标签(正则表达式匹配)的过程中,总是出现中断。如${project},系统会将该标签分为两个字符串 ${ 和 project} ,导致无法与正则表达式匹配,系统判断该段文本并不是标签,导致判断错误。

暂时未找到该问题的解决办法。网上说是因为使用了中文的括号 {。需要将标签先使用文本编辑器–记事本等编辑之后,再复制粘贴到word文档中,本人亲测之后,问题未得到解决。

三、结果展示

java使用POI导出word数据以及生成word表格相关推荐

  1. java的json导出excel_利用json生成excel表格

    起因: 之前利用反射生成excel导出,这个组件本来挺好用的,结果,坑爹的本地研发没有问题,生产环境却有问题.不知道什么原因直接导致服务重启,还重新加载类,直接导致jvm的永久区内存溢出. 异常: j ...

  2. java 导出word换行_Java 导出数据库表信息生成Word文档

    一.前言 最近看见朋友写了一个导出数据库生成word文档的业务,感觉很有意思,研究了一下,这里也拿出来与大家分享一波~ 先来看看生成的word文档效果吧 下面我们也来一起简单的实现吧 二.Java 导 ...

  3. Java 导出数据库表信息生成Word文档

    一.前言 最近看见朋友写了一个导出数据库生成word文档的业务,感觉很有意思,研究了一下,这里也拿出来与大家分享一波~ 先来看生成word文档效果吧 下面我们也来一起简单的实现吧 二.Java 导出数 ...

  4. java用poi导出word,Java使用POI导出Word文档的操作教程,poiword

    Java使用POI导出Word文档的操作教程,poiword 一.主要pom依赖 org.apache.poi poi-ooxml 3.16 二.需要导出word模板 三.相关导出代码 package ...

  5. java利用poi导出excel功能-附带图片导出

    java利用poi导出excel功能-附带图片导出 写在前面 最近刚离职,闲来无事,于是把上两家公司都有碰到过的需求但都没有去研究实现:即导出带图片的excel报表.于是就折腾了一下这个功能,研究出来 ...

  6. java中poi导出Excel表格(前台流文件接收)

    java中poi导出Excel表格,前端以流的方式接收,而非直接生成文件再下载,解决多台服务器部署后,路径地址不统一导致的下载问题. 生成Excel示例图: 2.代码说明 ① 在上次的基础上增加了底部 ...

  7. java poi 模板填数据库,java使用POI读取excel模版并向固定表格里填写数据详解

    java使用POI读取excel模版并向固定表格里填写数据详解:public class ExportExcelDemo { private HSSFWorkbook workbook = null; ...

  8. 使用poi导出大量数据到excel遇到的问题

    最近在工作遇到利用poi导出大量数据到excel并提供下载的运用场景,并遇到了一个问题,当数据量过大时(几十万),后台在进行数据写入excel中的过程会非常耗时,导致迟迟没有响应前台,结果数据还没导完 ...

  9. 导出数据库表信息生成Word文档(数据字典)

    平时多积累一些好工具,才能提高工作效率,早点下班 1. 关键字百度 Java 导出数据库表信息生成Word文档 gitee地址 2.拉取,运行 2.1 idea识别.导入maven工具 2.2 下载完 ...

最新文章

  1. 60篇论文入选,两度夺魁,“史上最难ECCV”商汤再攀高峰
  2. 应用流量管理,新网络管理必修课
  3. Spring3整合Ibatis3配置
  4. unity3d模拟树叶飘动_Unity3D独立游戏开发日记(一):动态生成树木
  5. 前端学习(807):简单数据类型传参
  6. Android仿ios二级菜单侧滑,仿IOS的列表项滑动菜单——ListItemMenu
  7. LeetCode 47. 全排列 II(回溯+搜索剪枝)
  8. 消息称京东方通过苹果认证 本月开始向iPhone 12供货OLED面板
  9. java校验参数防止攻击_程序员写接口参数校验,总是太多if else?一招让你避免体力活...
  10. Web页面的生命周期函数
  11. web前端项目实例网站_2020最全web前端项目实战课程(含项目实战+源码)
  12. 计算机组成:真正理解单周期处理器的“数据通路”
  13. 链家上海2018年9月二手房
  14. 加速度传感器和角度传感器
  15. JS获取按键的代码,Js如何屏蔽用户的按键,Js获取用户按键对应的ASII码(兼容所有浏览器)...
  16. edge扩展下载失败解决办法
  17. 当Androidstudio添加权限后仍然报错java.lang.SecurityException: Permission Denial
  18. Linux操作系统安全(一)
  19. 计算机算法常用术语中英对照
  20. 检测器评价指标-IOU

热门文章

  1. 用svg画一个微信订阅号的图标
  2. Java如何读取和操作上G文本数据
  3. RTC时钟学习总结附带其他小总结
  4. 安卓 jni 开发错误 undefined reference to __android_log_print
  5. 做什么事都要有风险意识
  6. 辛巴学院-Unity-剑英陪你零基础学c#系列(二)顺序
  7. 纯HTML也能访问数据库
  8. 《天空之城》助Twitter刷新纪录,新架构功不可没
  9. 淘宝官方的天天特卖活动应该如何进行进行设置?
  10. CSS正方体背面不可见