poi版本选3.10以上的 要不然插入图片 word会打不开

     <dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.11</version></dependency><dependency><groupId>org.apache.poi</groupId><artifactId>poi-ooxml</artifactId><version>3.11</version><exclusions><exclusion><artifactId>stax-api</artifactId><groupId>stax</groupId></exclusion></exclusions></dependency>

我下面代码中imgurl是base64编码,让后转的图片,你们使用的话,直接替换成图片路径地址就可以了

headList参数表示表格头部需要合并的集合,如果相邻左右或者上下位置的内容相同,就会自动合并单元格

        List<List<String>> headList = new ArrayList<>();headList.add(Arrays.asList(new String[]{"1","2","2","3","3","4","4","5"}));headList.add(Arrays.asList(new String[]{"1","6","7","8","9","10","11","5"}));headList.add(Arrays.asList(new String[]{"1","12","13","14","15","16","17","5"}));

dataList参数表示表格下方的数据集合,会根据headList中第一行的长度进行自动换行,传入 dataList参数的长度只要是headList(0)的长度的倍数即可.

其余的一些参数是我项目中使用到的,你们看着删一删就行了.

需要追加功能的话,创建一个WordExport 对象,然后一直调它的makeWord方法即可,需要生成新的word的话,重新创建对象.

package com.runstone.rsflow.word;import com.runstone.system.util.ConstantParam;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.Logger;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STMerge;
import sun.misc.BASE64Decoder;import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;public class WordExport {private XWPFDocument document;private FileOutputStream out;private File file;public File getFile() {return file;}public void setFile(File file) {this.file = file;}/**** @param title  pdf的标题* @param imgUrl 图片base64码* @param filePath  要保存word的路径  例:d:/* @param fileName  word的文件名   例:1.pdf* @param headList  表格头部的list数据* @param dataList  表格下方的内容数据   按顺序填入集合中即可* @param log*/public void makeWord (List<String> title, List<String> imgUrl, String filePath, String fileName,List<List<String>> headList, List<String> dataList, String note,File file, Logger log){fileName = fileName.replaceAll("/", "");fileName = fileName.replaceAll("\\\\","");SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");String format = simpleDateFormat.format(new Date());filePath += format+File.separator;String imgName = filePath+ UUID.randomUUID().toString()+".png";File f = new File(filePath);if (!f.exists()){f.mkdirs();}OutputStream imgOut = null;try {if (file.exists()){//添加标题XWPFParagraph titleParagraph2 = document.createParagraph();//设置段落居中titleParagraph2.setAlignment(ParagraphAlignment.CENTER);XWPFRun titleParagraphRun2 = titleParagraph2.createRun();titleParagraphRun2.setText("  ");titleParagraphRun2.setFontSize(50);}/*对于每个new的OutputStream对象,只能被document.write()执行一次保存操作*//*所以每次写入新的段落都要新建OutputStream,否则执行第二次会报错*/out = new FileOutputStream(file);for (int i=0;i<title.size();i++){if (i==0){if (StringUtils.isNotBlank(title.get(i))){//添加标题XWPFParagraph titleParagraph = document.createParagraph();//设置段落居中titleParagraph.setAlignment(ParagraphAlignment.CENTER);XWPFRun titleParagraphRun = titleParagraph.createRun();titleParagraphRun.setText(title.get(i));titleParagraphRun.setColor("000000");titleParagraphRun.setFontSize(20);}if (StringUtils.isNotBlank(note)){//添加标题XWPFParagraph titleParagraph = document.createParagraph();XWPFRun titleParagraphRun = titleParagraph.createRun();titleParagraphRun.setText(note);titleParagraphRun.setFontSize(10);}}else{//二级标题//添加标题XWPFParagraph titleParagraph = document.createParagraph();//设置段落居中XWPFRun titleParagraphRun = titleParagraph.createRun();titleParagraphRun.setText(title.get(i));titleParagraphRun.setColor("000000");titleParagraphRun.setFontSize(15);}}if (imgUrl!=null && imgUrl.size()>0){//基本信息表格XWPFTable imgTable = document.createTable((int)Math.ceil(Double.parseDouble(String.valueOf(imgUrl.size()))/2),imgUrl.size()>1?2:1);imgTable.getCTTbl().getTblPr().unsetTblBorders();int width = imgUrl.size()>1?190:505;int height = imgUrl.size()>1?75:205;XWPFParagraph paragraph = document.createParagraph();int row = 0;int col = 0;for (int i=0;i<imgUrl.size();i++){if (StringUtils.isNotBlank(imgUrl.get(i))){String img = imgUrl.get(i).replaceAll(" ", "+");String[] url = img.split("base64,");String u = url[1];// Base64解码byte[] b = new BASE64Decoder().decodeBuffer(u);// 生成图片File file1 = new File(imgName);imgOut = new FileOutputStream(file1);imgOut.write(b);imgOut.flush();imgOut.close();//插入图片XWPFRun run1 = paragraph.createRun();FileInputStream fileInputStream = new FileInputStream(file1);run1.addPicture(fileInputStream, XWPFDocument.PICTURE_TYPE_PNG, imgName, Units.toEMU(width), Units.toEMU(height));//imgTable.getRow(row).getCell(col).addParagraph(paragraph);fileInputStream.close();col++;if (col%2==0){row++;col=0;}file1.delete();}}if (headList!=null){makeData(headList,dataList);}FileOutputStream out = new FileOutputStream(new File(filePath+fileName));document.write(out);out.close();}} catch (Exception e) {log.error(ConstantParam.ERROR_SYSTEM,e);} finally {if (out!=null){try {out.close();} catch (IOException e) {log.error(ConstantParam.ERROR_SYSTEM,e);}}if (imgOut!=null){try {imgOut.close();} catch (IOException e) {log.error(ConstantParam.ERROR_SYSTEM,e);}}if (StringUtils.isNotBlank(imgName)){File file1 = new File(imgName);if (file1.exists()){file1.delete();}}}}public WordExport(String filePath,String fileName) {fileName = fileName.replaceAll("/", "");fileName = fileName.replaceAll("\\\\","");SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");String format = simpleDateFormat.format(new Date());filePath += format+File.separator;File file = new File(filePath+fileName);document = new XWPFDocument();    /*document对象可以只创建一次*/this.file = file;}/*** 合并单元格方法* @param list  表格头部数据 list中相连下标位置内容如果相同自动合并 上下位置内容相同自动合并* @param dataList  表格内容数据   按顺序填入集合中即可* @return*/private void makeData(List<List<String>> list,List<String> dataList) throws Exception{int length = list.get(0).size();List<List<Map<String,String>>> aa = new ArrayList<>();for (int i=0;i<list.size();i++){List<String> strings = list.get(i);int colNum = 1;List<Map<String,String>> bb = new ArrayList<>();for (int j=0;j <strings.size();j++){if (j+1<strings.size()){if (strings.get(j).equals(strings.get(j+1))){colNum++;}else{Map<String,String> map = new HashMap<>();map.put("value",strings.get(j));map.put("colspan",colNum+"");bb.add(map);for (int a=1;a<colNum;a++){bb.add(null);}colNum=1;}}else{Map<String,String> map = new HashMap<>();map.put("value",strings.get(j));map.put("colspan",colNum+"");bb.add(map);for (int a=1;a<colNum;a++){bb.add(null);}colNum=1;}}aa.add(bb);}for (int i=0;i<length;i++){int rowSpan = 1;for (int j=0;j<aa.size();j++){if (aa.get(j).get(i)==null){continue;}if (j+1<aa.size()){if (aa.get(j+1).get(i)!=null && aa.get(j).get(i).get("value").equals(aa.get(j+1).get(i).get("value"))&&aa.get(j).get(i).get("colspan").equals(aa.get(j+1).get(i).get("colspan"))){rowSpan++;}else{aa.get(j-rowSpan+1).get(i).put("rowSpan",rowSpan+"");for (int a=1;a<rowSpan;a++){aa.get(j-rowSpan+1+a).set(i,null);}rowSpan=1;}}else{aa.get(j-rowSpan+1).get(i).put("rowSpan",rowSpan+"");for (int a=1;a<rowSpan;a++){aa.get(j-rowSpan+1+a).set(i,null);}rowSpan=1;}}}List<List<Map<String,Boolean>>> mergeList = new ArrayList<>();for (int i=0;i<aa.size();i++){List<Map<String,Boolean>> list1 = new ArrayList<>();for (int j=0;j<aa.get(0).size();j++){Map<String, String> map1 = aa.get(i).get(j);if (map1!=null&&map1.size()>=3){int rowSpan = Integer.parseInt(map1.get("rowSpan"));int colspan = Integer.parseInt(map1.get("colspan"));if (colspan>1){aa.get(i).get(j).put("isColStart","true");for (int a=1;a<colspan;a++){Map<String,String> map = new HashMap<>();map.put("isColContinue","true");aa.get(i).set(j+a,map);}}if (rowSpan>1){aa.get(i).get(j).put("isRowStart","true");if (colspan>1){for (int a=1;a<rowSpan;a++){Map<String,String> map = new HashMap<>();map.put("isRowContinue","true");aa.get(i+a).set(j,map);for (int b=1;b<colspan;b++){Map<String,String> map2 = new HashMap<>();map2.put("isColContinue","true");map2.put("isRowContinue","true");aa.get(i+a).set(j+b,map2);}}}else{for (int a=1;a<rowSpan;a++){Map<String,String> map = new HashMap<>();map.put("isRowContinue","true");aa.get(i+a).set(j,map);}}}}}mergeList.add(list1);}//基本信息表格XWPFTable infoTable = document.createTable(dataList==null?list.size():list.size()+dataList.size()/list.get(0).size(),list.get(0).size());for (int i=0;i<list.size();i++){//表格第一行XWPFTableRow infoTableRowOne = infoTable.getRow(i);for (int j=0;j<list.get(0).size();j++){Map<String, String> map = aa.get(i).get(j);if (map.get("isColStart")!=null){infoTableRowOne.getCell(j).getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);//这是起点}if (map.get("isRowStart")!=null){infoTableRowOne.getCell(j).getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);//这是起点}if (map.get("isColContinue")!=null){infoTableRowOne.getCell(j).getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);//这是起点}if (map.get("isRowContinue")!=null){infoTableRowOne.getCell(j).getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);//这是起点}if (map.get("value")!=null){infoTableRowOne.getCell(j).setText(map.get("value"));}infoTableRowOne.getCell(j).getParagraphs().get(0).setAlignment(ParagraphAlignment.CENTER);  //设置水平居中infoTableRowOne.getCell(j).setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);  //设置垂直居中}}int row = list.size()-1;int col = 0;for (int i=0;i<dataList.size();i++){if (i%list.get(0).size()==0){row++;col = 0;}infoTable.getRow(row).getCell(col).setText(dataList.get(i));col++;}}
}

java poi生成word 插入表格,图片,自动合并单元格,并且可以在已存在的word上追加相关推荐

  1. Speedoffice(word)插入表格,如何合并单元格?

    在用Word制作表格的时候,有时插入的表格需要合并单元格,那怎么合并了?以最常用的speedoffice为例和大家分享一下. 1,首先运行软件,新建一份word插入表格作为演示,接着选中需要合并的单元 ...

  2. python pptx 关于在ppt里插入表格,调整合并单元格的问题

    python pptx 关于在ppt里插入表格,调整合并单元格的问题 需求 找到合并了的单元格 思路 判断是否是合并单元格 合并位置的记录 合并 代码 需求 首先我这是为了从word里面将内容导到pp ...

  3. FreeMarker生成word-定义模板步骤(带表格且含合并单元格)

    本文介绍使用freeMark生成包含表格合并单元的word如何制作模板, 合并单元格主要使用 <w:vmerge w:val='restart'/>和<w:vmerge/>实现 ...

  4. easypoi利用模板导出图片到Excel;解决easypoi导出图片到合并单元格单元格被拉伸的问题

    easypoi的封装是非常好的,用起来很简单. 官方教程地址:http://easypoi.mydoc.io/ 但是在使用模板导出图片到合并单元格时出问题了,官网找了好几遍没找到方案. 其实官方早就实 ...

  5. java导出excel 边框不全_POI 导出Excel合并单元格后部分边框不显示

    用户需要导出自定义表格,其中合并单元格样式遇到的问题,合并后只显示第一行第一列的边框,其他边框不显示,于是遍查百度,寻到一点思路 ①了解Excel绘制原理 ②了解绘制Excel顺序 ③绘制Excel单 ...

  6. Java 利用hutool工具实现导出excel并合并单元格

    Java 利用hutool工具实现导出excel并合并单元格 controller层调用service,就一个核心方法,没错就下面这个代码就能实现了.前提是项目里面要引用hutool包.把我这个复制到 ...

  7. PyQT5 (四十六) 在 QTableWidget 表格中设置合并单元格 的案例

    在 QTableWidget 表格中设置合并单元格 的案例 setSpan(row, col, 要合并的行数, 要合并的列数) import sysfrom PyQt5 import QtPrintS ...

  8. 动态处理表格多行合并单元格、同时解决hover错乱问题 - Vue Element Table

    简介: el-table单元格合并,处理hover错乱问题,自定义底部合计栏. 如图所示: 源码(复制另存txt,修改.html直接运行) <!DOCTYPE html> <html ...

  9. 记录【vxe-table】自动合并单元格

    <vxe-table@cell-click="handleClickCell":span-method="spanMethods" //自动合并单元格:d ...

最新文章

  1. 给大家推荐8个SpringBoot精选项目
  2. LeetCode 225. Implement Stack using Queues--用队列实现栈--C++解法
  3. 一个页面多个swiper问题解决
  4. 基于IPV6的数据包分析
  5. java报错误设置属性值_java – 设置属性值时出错;嵌套异常是org.springframework.beans.NotWritablePropertyException:...
  6. TDSQL 全时态数据库系统 -- 典型案例
  7. 关于ReetrantLock
  8. php 数组的处理,php 数组处理
  9. js计算html的font-size
  10. 已经编译好的OpenCV4.5.1----win10(cuda10.0 cudnn7.6.5)
  11. 应用系统适配迁移方案
  12. 矩阵专业词汇英文对照
  13. filezilla里怎么解决中文乱码问题
  14. linux进化树分析的软件,一款好用的进化树可视化编辑软件
  15. Python中循环题目二的练习(for、while、if)
  16. SQL Server视频总结(一):SQL Server概述
  17. python页面转图片_网页转图片_技术分享 - SegmentFault 思否
  18. L298N驱动模块电路图
  19. Python实现基于用户的协同过滤推荐算法构建电影推荐系统
  20. 【游戏开发创新】520程序员的浪漫,给CSDN近两万的粉丝比心心(python爬虫 | Unity循环复用列表 | 头像加载与缓存)

热门文章

  1. windows7 切换共享文件登录域账户
  2. 如何取消shift粘滞键?Win11粘滞键彻底关闭的方法
  3. xshell退格键无法使用的解决方法
  4. 在主窗口中增加绘图类控件时(以QPainter为例)时不显示内容的问题(不应该加addStretch)
  5. 好看的校园万能墙小程序源码
  6. vs2017中 如何使用npm命令
  7. c语言字strcpy,c语言,strcpy
  8. Win10禁用不常用的多余的无用服务
  9. 监听并自添加windows防火墙规则批处理FOR WIN10
  10. codemirror6 版本不包含 mode,addon 等目录