java基于POI实现向word模板填充数据

在做项目的时候遇到需要将多张表单导出为word,就想到了这个方法。

注意:XWPFDocument不支持doc类型文档,做模板的时候要另存为docx。

示例模板:

填充结果:

maven工程在pom.xml文件引入依赖:

     <dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>4.0.0</version></dependency><!-- https://mvnrepository.com/artifact/org.apache.poi/poi --><dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>4.0.0</version></dependency>
import java.io.*;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFFooter;
import org.apache.poi.xwpf.usermodel.XWPFHeader;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
/*** 替换段落里面的变量* @param paragraph* @param map*/public static void replaceParagraph(XWPFParagraph paragraph,Map<String,Object> map){List<XWPFRun> runs = paragraph.getRuns();for (int i = 0; i < runs.size(); i++) {XWPFRun run = runs.get(i);String tkey = run.toString();if(tkey==null){return;}for (String key : map.keySet()) {if(tkey.equals(key)){int size = run.getFontSize();if(size==-1){size=14;}String fontFamily = run.getFontFamily();//因为直接调用setText()方法替换文本时,会在底层重新创建一个run,所以在设置文本之前要先删除当前runparagraph.removeRun(i);if(map!=null && map.get(key)!=null){String runText = map.get(key).toString();if(runText!=null){if(runText.indexOf("\r\n")!=-1){String[] texts = runText.split("\r\n");List<String> tmp = new ArrayList<>();for (String text : texts) {if(text!=null && text.length()!=0){tmp.add(text);}}texts = tmp.toArray(new String[0]);for (int n = 0; n < texts.length; n++) {XWPFRun newRun = paragraph.createRun();newRun.setText("    "+texts[n].trim());if(texts.length>1 && n!=texts.length-1){newRun.addBreak();}newRun.setText(runText);newRun.setFontSize(size);newRun.setFontFamily(fontFamily);}}else if(runText.indexOf("\n")!=-1){String[] texts = runText.split("\n");List<String> tmp = new ArrayList<>();for (String text : texts) {if(text!=null && text.length()!=0){tmp.add(text.trim());}}texts = tmp.toArray(new String[0]);for (int n = 0; n < texts.length; n++) {XWPFRun newRun = paragraph.createRun();newRun.setText("    "+texts[n].trim());if(texts.length>1 && n!=texts.length-1){newRun.addBreak();}newRun.setFontSize(size);newRun.setFontFamily(fontFamily);}}else{//重新创建一个run用于设置文本XWPFRun newrun = paragraph.insertNewRun(i);newrun.setText(runText);newrun.setFontSize(size);newrun.setFontFamily(fontFamily);}}}}}}}
    /*** 替换页眉里面的变量* @param Header* @param map*/public static void replaceHeader(XWPFHeader Header,Map<String,Object> map){//获取表List<XWPFTable> tableList = Header.getTables();if(tableList!=null && tableList.size()>0){for (int i = 0; i < tableList.size(); i++) {XWPFTable table = tableList.get(i);//获取行List<XWPFTableRow> rows = table.getRows();for (XWPFTableRow row : rows) {//获取单元格List<XWPFTableCell> cells = row.getTableCells();for (XWPFTableCell cell : cells) {//获取单元格内容List<XWPFParagraph> paragraphs = cell.getParagraphs();for (XWPFParagraph paragraph : paragraphs) {//                            paragraph.setAlignment(ParagraphAlignment.LEFT);replaceParagraph(paragraph,map);}}}}}else {List<XWPFParagraph> paragraphs = Header.getParagraphs();for (XWPFParagraph paragraph : paragraphs) {//                paragraph.setAlignment(ParagraphAlignment.LEFT);replaceParagraph(paragraph,map);}}}
/*** 替换页脚里面表格的变量* @param Footer* @param map*/public static void replaceFooter(XWPFFooter Footer, Map<String,Object> map){//获取表List<XWPFTable> tableList = Footer.getTables();if(tableList!=null && tableList.size()>0){for (int i = 0; i < tableList.size(); i++) {XWPFTable table = tableList.get(i);//获取行List<XWPFTableRow> rows = table.getRows();//获取单元格for (XWPFTableRow row : rows) {List<XWPFTableCell> cells = row.getTableCells();for (XWPFTableCell cell : cells) {//获取段落List<XWPFParagraph> paragraphs = cell.getParagraphs();for (XWPFParagraph paragraph : paragraphs) {//                            paragraph.setAlignment(ParagraphAlignment.LEFT);replaceParagraph(paragraph,map);}}}}}else {List<XWPFParagraph> paragraphs = Footer.getParagraphs();for (XWPFParagraph paragraph : paragraphs) {//                paragraph.setAlignment(ParagraphAlignment.LEFT);replaceParagraph(paragraph,map);}}}
/*** 替换表格里面的变量* @param document* @param map*/public static void replaceInTable(XWPFDocument document,Map<String,Object> map) throws Exception {Iterator<XWPFTable> iterator = document.getTablesIterator();while (iterator.hasNext()){//获取表XWPFTable table = iterator.next();//获取行List<XWPFTableRow> rows = table.getRows();for (XWPFTableRow row : rows) {//获取单元格List<XWPFTableCell> cells = row.getTableCells();for (XWPFTableCell cell : cells) {List<XWPFParagraph> paragraphs = cell.getParagraphs();for (XWPFParagraph paragraph : paragraphs) {//paragraph.setAlignment(ParagraphAlignment.LEFT);replaceParagraph(paragraph,map);}}}}}
/*** 导出docx* @param templatePath* @param outPath* @param map*/public static boolean  getDocx(String templatePath, String outPath,Map<String, Object> map){XWPFDocument document = null;try{File file = new File(templatePath);InputStream in = new FileInputStream(file);document = new XWPFDocument(in);//替换页眉变量Iterator<XWPFHeader> headerIterator = document.getHeaderList().iterator();while (headerIterator.hasNext()){XWPFHeader header = headerIterator.next();replaceHeader(header,map);}//替换页脚变量Iterator<XWPFFooter> footerIterator = document.getFooterList().iterator();while (footerIterator.hasNext()){XWPFFooter footer = footerIterator.next();replaceFooter(footer,map);}//替换表格里面的变量replaceInTable(document,map);// 如果文件夹不存在 则建立新文件夹File dir= new File(outPath);if (!dir.exists() == false) {dir.mkdirs();}ByteArrayOutputStream bos = new ByteArrayOutputStream();OutputStream out = new FileOutputStream(outPath);document.write(bos);out.write(bos.toByteArray());bos.close();out.close();return true;}catch (Exception e){e.printStackTrace();return false;} finally{try{if ( document != null ){document.close();}}catch (IOException e){e.printStackTrace();}}}
//测试
public static void main(String[] args) throws Exception{HashMap map = new HashMap();map.put("${title}", "人员信息表");map.put("${name}", "张三");map.put("${age}", "20岁");map.put("${height}", "180cm");map.put("${weight}", "70kg");     String templatePath = "D:\\1.docx";String outPath = "D:\\2.docx";getDocx(templatePath , outPath , map);}

利用poi向word模板填充数据相关推荐

  1. Java poi word模板填充数据、复制行删除行

    Java poi word模板填充数据 1.明细表格式 ${list_xxxxx} 普通格式 ${xxxxxx} 2.replaceInTable方法中 table.removeRow(2); 第三行 ...

  2. 利用poi读取word模板文件生成新的word文档

    利用poi读取word模板文件生成新的word文档 利用poi读取word模板文件,并回填逻辑数据,生成并导出需要的word文档源码.解决模板读取异常问题,提供wordUtils工具类(各种功能实现) ...

  3. java word模板poi生成文件_利用poi读取word模板文件生成新的word文档

    利用poi读取word模板文件生成新的word文档 利用poi读取word模板文件,并回填逻辑数据,生成并导出需要的word文档源码.解决模板读取异常问题,提供wordUtils工具类(各种功能实现) ...

  4. Java根据word模板填充数据(使用poi-tl)

    poi-tl 是Word模板引擎,使用Word模板和数据创建Word文档. 文档地址: Poi-tl Documentation 里面详细说明了如何使用,已在项目中实践过,确实很好用的一个插件. 依赖 ...

  5. word模板填充数据

    1.首先创建word模板文件aaa.docx 需要填充的字段用如下方式表示 2.导入依赖 <dependency><groupId>com.deepoove</group ...

  6. vb 变量赋值为当前选定单元格_第7篇:根据Excel选定行对Word模板填充数据(补充修改)...

    题外:由于漏掉了勾选Microsoft Word 16.0 Object Library这个关键步骤(不勾选是无法导出的),故修改后再次发出.本期我是从知乎上的郭大牛老师那里学的,非常建议大家去阅读, ...

  7. 无插件,无com组件,利用EXCEL、WORD模板做数据导出(一)

    本次随笔主要讲述着工作中是如何解决数据导出的,对于数据导出到excel在日常工作中大家还是比较常用的,那导出到word呢,改如何处理呢,简单的页面导出问题应该不大,但是如果是标准的公文导出呢,要保证其 ...

  8. Python 使用Word模板填充数据

    工作需要使用Word模板,生成报告,安装pip install docxtpl. 首先挖出需要填充数据的地方,设计好数据返回的架构template_path为模板绝对路径: resulte_conte ...

  9. Java实现根据Word模板填充表格数据(poi方式),以及doc和docx转PDF,最全最详细版本,解决外部引用jar在linux上报ClassNotFound的问题。

    Java实现根据Word模板填充表格数据(poi方式),以及doc和docx转PDF,最全最详细版本,解决外部引用jar在linux上报ClassNotFound的问题. 适用场景: 1.固定格式的W ...

最新文章

  1. java.lang.NoSuchMethodException 错误
  2. STM32’s I2C 硬件BUG引发的血案
  3. 解决python最新版无法安装TensorFlow,导入TensorFlow
  4. 32G内存手机到底够用吗?看完泪崩
  5. 条款5:了解C++默默编写并调用哪些函数(Know what functions C++ silently writes and calls)...
  6. ADMM算法的应用: 降低SDP算法复杂度
  7. 我用Python写了一个做题软件控制台版。(支持Mod)
  8. 点击换图 秀米的svg_能换色的.svg图片怎么用?看这篇就够了!
  9. Pointofix非常好用的一款屏幕书写软件
  10. 【目标检测】Receptive Field Block Net for Accurate and Fast Object Detection论文理解
  11. 抗击肺炎,我们能做到的,就是别让爱隔离——python分析B站三个视频弹幕内容,云图数据。
  12. 观《达芬奇的人生密码》有感——艺工交叉的智慧
  13. 小米12X、小米12、小米12 Pro参数对比
  14. caused by: java.lang.outofmemory_hadoop运行java.lang.OutOfMemoryError:java heap space错误。
  15. 野芯CM4_USB3.0x4底板对比树莓派4B的USB3.0速度测试
  16. 微信小程序-一次性订阅消息推送
  17. 1. Linux命令之ps:查看进程状态
  18. 读书-《番茄工作法图解》
  19. 电脑横机服务器维修,国产电脑横机操作和维修方法
  20. 国产运动耳机品牌排行榜、2022运动耳机款式盘点

热门文章

  1. 8个超酷炫仿苹果应用的HTML5动画
  2. Python-Flask开发微电影网站(五)
  3. NPOI合并单元格后边框显示不正确?
  4. 比基尼会画嘛?女生泳衣会画嘛?
  5. 转换流(将字节流转换为字符流)
  6. http://a.codekk.com/detail/Android/grumoon/Volley 源码解析
  7. 如何判断一个对象里面的属性值都为空
  8. LXD使用踩过的坑1——网络配置(后续遇到坑再更新......)
  9. VREP教程--**BubbleRob tutorial**
  10. [Linux运维基础]全家桶详解!Linux中RPM包、wget下载、YUM安装、tar包、zip等包管理方式区别与参数详解,附wget下载源码包编译安装方法