java POI对word中的表格动态插入固定数据,以及插入不具体的数据

遇到个项目本来是用Execl导出的,相对简单,客户要求用Word导出,并按照他们给的模板进行导出;
从网上百度了一下,然后自己修改下,实现了对word中的同一张表格同时进行通过key替换操作,以及从特定的行开始插入数据,根据是需要插入的数据自动增加行等;下面直接上主要代码,都有注释。

maven依赖包引入

<dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId>
</dependency>

工具类

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;import org.apache.poi.POIXMLDocument;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
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;public class WordUtil {/*** 根据模板生成新word文档* 对表格是进行替换以及插入* @param inputUrl 模板存放地址* @param outPutUrl 新文档存放地址* @param textMap 需要替换的信息集合 * @param tableList 需要插入的表格信息集合* @return 成功返回true,失败返回false*/public static boolean changWord(String inputUrl, String outputUrl,Map<String, String> textMap, List<String[]> tableList) {//模板转换默认成功boolean changeFlag = true;try {//获取docx解析对象XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(inputUrl));//解析替换文本段落对象WordUtil.changeText(document, textMap);//解析替换表格对象WordUtil.changeTable(document, textMap, tableList);//生成新的wordFile file = new File(outputUrl);FileOutputStream stream = new FileOutputStream(file);document.write(stream);stream.close();} catch (IOException e) {e.printStackTrace();changeFlag = false;}return changeFlag;}/*** 替换段落文本* @param document docx解析对象* @param textMap 需要替换的信息集合*/public static void changeText(XWPFDocument document, Map<String, String> textMap){//获取段落集合List<XWPFParagraph> paragraphs = document.getParagraphs();for (XWPFParagraph paragraph : paragraphs) {//判断此段落时候需要进行替换String text = paragraph.getText();if(checkText(text)){List<XWPFRun> runs = paragraph.getRuns();for (XWPFRun run : runs) {//替换模板原来位置run.setText(changeValue(run.toString(), textMap),0);}}}}/*** 替换表格对象方法* @param document docx解析对象* @param textMap 需要替换的信息集合* @param tableList 需要插入的表格信息集合*/public static void changeTable(XWPFDocument document, Map<String, String> textMap,List<String[]> tableList){//获取表格对象集合List<XWPFTable> tables = document.getTables();//获取第一个表格   根据实际模板情况 决定去第几个word中的表格XWPFTable table = tables.get(0);//表格中的内容替换List<XWPFTableRow> rows = table.getRows();eachTable(rows, textMap);//遍历表格,并替换模板//向特定位置 行插入数据insertTable(table, tableList);}/*** 遍历表格* @param rows 表格行对象* @param textMap 需要替换的信息集合*/public static void eachTable(List<XWPFTableRow> rows ,Map<String, String> textMap){for (XWPFTableRow row : rows) {List<XWPFTableCell> cells = row.getTableCells();for (XWPFTableCell cell : cells) {//判断单元格是否需要替换if(checkText(cell.getText())){List<XWPFParagraph> paragraphs = cell.getParagraphs();for (XWPFParagraph paragraph : paragraphs) {List<XWPFRun> runs = paragraph.getRuns();for (XWPFRun run : runs) {run.setText(changeValue(run.toString(), textMap),0);}}}}}}/*** 为表格插入数据,行数不够添加新行* @param table 需要插入数据的表格* @param tableList 插入数据集合*/public static void insertTable(XWPFTable table, List<String[]> tableList){//创建行,根据需要插入的数据添加新行,不处理表头//判断需要插入的数量if (tableList.size() > 5) {//我的模板预留了五行for (int i=0;i<tableList.size()-4;i++) {insertRow(table,10,14);}} //遍历表格插入数据List<XWPFTableRow> rows = table.getRows();for(int i = 9; i < tableList.size() + 9; i++){XWPFTableRow newRow = table.getRow(i);List<XWPFTableCell> cells = newRow.getTableCells();for(int j = 0; j < cells.size(); j++){XWPFTableCell cell = cells.get(j);cell.setText(tableList.get(i-9)[j]);}}}/*** 判断文本中时候包含$* @param text 文本* @return 包含返回true,不包含返回false*/public static boolean checkText(String text){boolean check  =  false;if(text.indexOf("$")!= -1){check = true;}return check;}/*** insertRow 在word表格中指定位置插入一行,并将某一行的样式复制到新增行* @param copyrowIndex 需要复制的行位置* @param newrowIndex 需要新增一行的位置* */public static void insertRow(XWPFTable table, int copyrowIndex, int newrowIndex) {// 在表格中指定的位置新增一行XWPFTableRow targetRow = table.insertNewTableRow(newrowIndex);// 获取需要复制行对象XWPFTableRow copyRow = table.getRow(copyrowIndex);//复制行对象targetRow.getCtRow().setTrPr(copyRow.getCtRow().getTrPr());//或许需要复制的行的列List<XWPFTableCell> copyCells = copyRow.getTableCells();//复制列对象XWPFTableCell targetCell = null;for (int i = 0; i < copyCells.size(); i++) {XWPFTableCell copyCell = copyCells.get(i);targetCell = targetRow.addNewTableCell();targetCell.getCTTc().setTcPr(copyCell.getCTTc().getTcPr());if (copyCell.getParagraphs() != null && copyCell.getParagraphs().size() > 0) {targetCell.getParagraphs().get(0).getCTP().setPPr(copyCell.getParagraphs().get(0).getCTP().getPPr());if (copyCell.getParagraphs().get(0).getRuns() != null&& copyCell.getParagraphs().get(0).getRuns().size() > 0) {XWPFRun cellR = targetCell.getParagraphs().get(0).createRun();cellR.setBold(copyCell.getParagraphs().get(0).getRuns().get(0).isBold());} } }}/*** 匹配传入信息集合与模板* @param value 模板需要替换的区域* @param textMap 传入信息集合* @return 模板需要替换区域信息集合对应值*/public static String changeValue(String value, Map<String, String> textMap){Set<Entry<String, String>> textSets = textMap.entrySet();for (Entry<String, String> textSet : textSets) {//匹配模板与替换值 格式${key}String key = "${"+textSet.getKey()+"}";if(value.indexOf(key)!= -1){value = textSet.getValue();}}//模板未匹配到区域替换为空if(checkText(value)){value = "";}return value;}public static void main(String[] args) {//模板文件地址String inputUrl = "E:\\beian\\demo1.docx";//新生产的模板文件String outputUrl = "E:\\beian\\demo3.docx";Map<String, String> testMap = new HashMap<String, String>();testMap.put("type0", "注销");testMap.put("application", "票据系统");testMap.put("dept", "信息中心");testMap.put("unit", "111111");testMap.put("type1", "2");testMap.put("type2", "3");testMap.put("type3", "4");testMap.put("type4", "5");List<String[]> testList = new ArrayList<String[]>();testList.add(new String[]{"1","Q1","W1","E1","R1","T1"});testList.add(new String[]{"2","Q2","W2","E2","R2","T2"});testList.add(new String[]{"3","Q3","W3","E3","R3","T3"});testList.add(new String[]{"4","Q4","W4","E4","R4","T4"});testList.add(new String[]{"5","Q5","W5","E5","R5","T5"});testList.add(new String[]{"6","Q6","W6","E6","R6","T6"});testList.add(new String[]{"7","Q7","W7","E7","R7","T7"});WordUtil.changWord(inputUrl, outputUrl, testMap, testList);}}

模板

${type0}中的内容 为要替换的部分,用text写,然后复制进来, 不然可能无法替换,直接在word中写,会可能被认为一整个对象,无法替换成功

结果:

参考了这两位大佬的
https://www.jianshu.com/p/6603b1ea3ad1
https://blog.csdn.net/qq_36880602/article/details/105750590

java POI对word中的表格动态插入固定数据,以及插入不确定数量的的数据相关推荐

  1. POI操作Word中的表格XWPFTable,在指定位置插入行

    最近由于客户使用Word文档展示表格中的数据,我TM...Excel它不香嘛,为什么要用Word去展示表格呢??? 但是呢.客户就是上帝,上帝让我们干嘛我们就要干嘛. 1:有这样一个需求,在已有的Wo ...

  2. java poi读取word中附件_Java POI导入word, 带图片

    1.导入文件示例,word中简历表格模板 2.代码示例分两部分,一部分读取图片 /** * 导入word(基本信息,word格式) * @param staffId * @param baseInfo ...

  3. java poi 读word (doc,docx)表格

    项目场景: 最近公司将线下流程线上话,提供上传模板的功能,很多表格都是在word里面生成的,找了很多资料处理docx 跟doc 最后docx 勉强可以用,doc还是不完善,最后只能沟通 限制上传doc ...

  4. java poi读取word中附件_数据导出生成word附件使用POI的XWPFTemplate对象

    比较常用的实现Java导入.导出Excel的技术有两种Jakarta POI和Java Excel. Jakarta POI 是一套用于访问微软格式文档的Java API.Jakarta POI有很多 ...

  5. java poi读取word中附件_java用poi实现对word读取和修改操作

    java编程要实现对word的操作没有vb那种编程语言来得容易,得借助一些开源组件,其中就包括jacob.poi等, 而poi应用得最为广泛,对word2003和2007的读和写word操作都十分方便 ...

  6. poi解析word中的表格

    解析word简历,使用poi解析word表格研究记录如下: package poi;import java.io.File; import java.io.FileInputStream; impor ...

  7. Java在线合并word中的表格,并对其进行赋值

    前言: 在OA系统中,有时我们需要在线打开文档,文档中免不了有word表格,并且我们希望能够通过代码对表格单元格进行一些合并/赋值的的操作.这就需要我们学习微软activex控件的使用了.但是这需要开 ...

  8. java poi读取word中附件_java poi word读取

    用 poi 读取word文件 . 老是报错 org.apache.poi.poifs.filesystem.NotOLE2FileException: Invalid header signature ...

  9. java使用poi在word中生成柱状图、折线图、饼图、柱状图+折线图组合图、动态表格、文本替换、图片替换、更新内置Excel数据、更新插入的文本框内容、合并表格单元格;

    本文参考地址:https://blog.csdn.net/wangxiaoyingWXY/article/details/95377533 在参考文章的基础上,增加了扩展.感谢被参考的妹子.另外该博客 ...

最新文章

  1. 如何强制Visual Studio重新生成aspx / ascx文件的.designer文件?
  2. 关于重装系统或还原系统
  3. Kubernetes通过containerd访问registry的30443端口
  4. 计算机网络(谢希仁第八版)第二章:物理层
  5. VTK:PolyData之IterateOverLines
  6. linux cmake 安装mysql5.5.11,以及更高版本
  7. java猜拳游戏代码_Java实现简单猜拳游戏
  8. ES6之const命令
  9. 打造自己的.NET Core项目模板
  10. 第一次当项目经理压力大_项目经理不想被甩锅,你要这样做进度管理
  11. python是什么类型的编程语言-python是一种什么类型的语言
  12. 一个关于Schema的问题,请求帮助
  13. HDU 1195 Open the Lock BFS
  14. 奇怪的技能又增加了,我学会了用ETS5配置KNX
  15. C++中rapidxml用法及例子
  16. 用USRP-LW N210搭建软件雷达系统
  17. 惠普星14 指纹识别功能安装
  18. 用计算机刻录光盘,图文详解怎么用电脑刻录光盘
  19. linux清理unbuntu无用空间,如何给Ubuntu系统清理垃圾
  20. IPv4地址--公网地址可以有多少

热门文章

  1. Docker 4.2:Docker 公有镜像仓库 - 阿里云容器镜像服务
  2. [技术分享]-Servlet/tomcat/spring mvc之间关系
  3. 应用礼学赋能新员工职业素养提升
  4. Win11(Win10类似)的快速设置与优化 ——《环境配置》系列文章
  5. 你能说更多关于崩坏3琪亚娜的细节吗
  6. 除了苹果耳机外哪个无线耳机好?苹果蓝牙耳机平替推荐
  7. 云安全成下一个市场热点,三方云安全厂商出路在哪里?
  8. Java开发微信公众号-接口测试帐号接口配置及Java源代码
  9. mysql auto increment 插入_MySQL里AUTO_INCREMENT表里插入0值的问题
  10. python:defaultdict