poi根据模板导出word(包含图片、动态生成表格、合并单元格)(亲测有效)

准备工作:

1.需要的jar(jar包在资源处已上传,可下载)

2.创建docx模板(doc不可以)

第一步:准备好jar(这里面的 ooxml-schemas-1.1.jar 大家可以尝试用poi-shemas-3.12-20150511.jar替换试试,但是偶尔会报java.lang.NoSuchMethodException: org.openxmlformats.schemas.wordprocessingml.x2006.....等错误,网络说poi-shemas-3.12-20150511.jar是简化版,需要用 ooxml-schemas-1.1.jar替换)

第二步:准备好docx模板(这里我写入了四个表格,根据您的需要制作,${date} 是段落部分, $符号不能没有,代码中需要判断替换的)

准备工作完成  下面是代码部分

BaseXWPFDocument.java

package word;

import java.io.IOException;
import java.io.InputStream;

import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlToken;
import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTInline;

/**
 * 自定义 XWPFDocument,并重写 createPicture()方法
 */
public class BaseXWPFDocument extends XWPFDocument{
    public BaseXWPFDocument(InputStream in) throws IOException {
        super(in);
    }

    public BaseXWPFDocument() {
        super();
    }

    public BaseXWPFDocument(OPCPackage pkg) throws IOException {
        super(pkg);
    }

    /**
     * @param id
     * @param width 宽
     * @param height 高
     * @param paragraph  段落
     */
    public void createPicture(int id, int width, int height,XWPFParagraph paragraph) {
        final int EMU = 9525;
        width *= EMU;
        height *= EMU;
        String blipId = getAllPictures().get(id).getPackageRelationship().getId();
        CTInline inline = paragraph.createRun().getCTR().addNewDrawing().addNewInline();

        System.out.println(blipId+":"+inline);

        String picXml = ""
                + "<a:graphic xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\">"
                + "   <a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">"
                + "      <pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">"
                + "         <pic:nvPicPr>" + "            <pic:cNvPr id=\""
                + id
                + "\" name=\"Generated\"/>"
                + "            <pic:cNvPicPr/>"
                + "         </pic:nvPicPr>"
                + "         <pic:blipFill>"
                + "            <a:blip r:embed=\""
                + blipId
                + "\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"/>"
                + "            <a:stretch>"
                + "               <a:fillRect/>"
                + "            </a:stretch>"
                + "         </pic:blipFill>"
                + "         <pic:spPr>"
                + "            <a:xfrm>"
                + "               <a:off x=\"0\" y=\"0\"/>"
                + "               <a:ext cx=\""
                + width
                + "\" cy=\""
                + height
                + "\"/>"
                + "            </a:xfrm>"
                + "            <a:prstGeom prst=\"rect\">"
                + "               <a:avLst/>"
                + "            </a:prstGeom>"
                + "         </pic:spPr>"
                + "      </pic:pic>"
                + "   </a:graphicData>" + "</a:graphic>";

        inline.addNewGraphic().addNewGraphicData();
        XmlToken xmlToken = null;
        try {
            xmlToken = XmlToken.Factory.parse(picXml);
        } catch (XmlException xe) {
            xe.printStackTrace();
        }
        inline.set(xmlToken);

        inline.setDistT(0);
        inline.setDistB(0);
        inline.setDistL(0);
        inline.setDistR(0);

        CTPositiveSize2D extent = inline.addNewExtent();
        extent.setCx(width);
        extent.setCy(height);

        CTNonVisualDrawingProps docPr = inline.addNewDocPr();
        docPr.setId(id);
        docPr.setName("图片名称" + id);
        docPr.setDescr("描述部分");
    }
}

CrtWordUtils.java

package word;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.poi.POIXMLDocument;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
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;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTHMerge;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTc;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcBorders;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTcPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTVMerge;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STBorder;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STJc;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STMerge;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STVerticalJc;


/**
 * 生成word工具类
 */
public class CrtWordUtils{
	
	//private static Log logger = LogFactory.getLog(CrtWordUtils.class);
	
    /**
     * 根据模板生成word文档
     * @param inputUrl 模板路径
     * @param textMap 需要替换的文本内容
     * @param mapList 需要动态生成的内容
     * @return
     */
    public static BaseXWPFDocument changWord(String inputUrl, Map<String, Object> textMap, List<Object> mapList) {
        BaseXWPFDocument document = null;
        try {
            //获取docx解析对象
            document = new BaseXWPFDocument(POIXMLDocument.openPackage(inputUrl));
            //解析替换文本段落对象
            //logger.info("CrtWordUtils--生成word中文本段落开始...");
            changeText(document, textMap);
            //logger.info("CrtWordUtils--生成word中文本段落结束...");
            //解析替换表格对象
            //logger.info("CrtWordUtils--生成word中表格开始...");
            changeTable(document,textMap, mapList);
            //logger.info("CrtWordUtils--生成word中表格结束...");
        } catch (IOException e) {
        	//logger.error("CrtWordUtils--生成word失败,原因:"+e.getMessage());
        }
        return document;
    }

    /**
     * 替换表格对象方法
     * @param document docx解析对象
     * @param mapList 需要动态生成的内容
     */
    public static void changeTable(BaseXWPFDocument document,Map<String, Object> textMap, List<Object> mapList){
        //获取表格对象集合
        List<XWPFTable> tables = document.getTables();
        
      //循环所有需要进行替换的文本,进行替换
        for (int i = 0; i < tables.size(); i++) {
            XWPFTable table = tables.get(i);
            
            
            XWPFParagraph p = document.getParagraphArray(0);
            p.setAlignment(ParagraphAlignment.LEFT);
            XWPFRun run = p.insertNewRun(0);
            
            List<XWPFTableRow> rows = table.getRows();
            
            //--------------------------------在第二个表格的第一行第一列的框中插入图片-----------------------------------
            if(i == 1){
            	 XWPFTableRow rowTest = table.getRow(0);
                 XWPFTableCell imageCell = rowTest.getCell(0);
                 List<XWPFParagraph> paragraphs = imageCell.getParagraphs();
                 XWPFParagraph newPara = paragraphs.get(0);
                 XWPFRun imageCellRunn = newPara.createRun();
                 try {
					imageCellRunn.addPicture(new FileInputStream("D:/1.png"), BaseXWPFDocument.PICTURE_TYPE_PNG, "1.png", Units.toEMU(40), Units.toEMU(30));
				} catch (Exception e) {
					e.printStackTrace();
				}
                 run.addBreak();
            }
          //--------------------------------在第二个表格的第一行第一列的框中插入图片-----------------------------------
            
            if(checkText(table.getText())){
                //遍历表格,并替换模板
                eachTable(document,rows, textMap);
            }
        }
        
        int index=0;
        //操作word中的表格
        for (int i = 0; i < tables.size(); i++) {
            //只处理行数大于等于2的表格,且不循环表头
            XWPFTable table = tables.get(i);
            List<String[]> list = (List<String[]>) mapList.get(index);
            if (!list.isEmpty()){
            	//logger.info("CrtWordUtils--生成word中表格第"+(index+1)+"个表格开始");
            	if(i == 3){
            		changeTable_quality(document, mapList);
            	}else{
            		insertTable(table,list,i);
                	//logger.info("CrtWordUtils--生成word中表格第"+(index+1)+"个表格结束");
                    if(i == 1){//第二个表格需要列合并
    	                List<Integer[]> indexList = startEnd(list);
    	                for (int c=0;c<indexList.size();c++){ //合并行
    	                	//logger.info("CrtWordUtils--生成word中表格需要合并的表格开始...");
    	                    mergeCellVertically(table,0,indexList.get(c)[0]+2,indexList.get(c)[1]+2);
    	                    //mergeCellVertically(table,1,indexList.get(c)[0]+1,indexList.get(c)[1]+1);
    	                    // logger.info("CrtWordUtils--生成word中表格需要合并的表格结束...");
    	                }
                    }
            	}
            }
            index++;
        }
    }
    public static void changeTable_quality(BaseXWPFDocument document, List<Object> mapList){
    	//获取表格对象集合
    	List<XWPFTable> tables = document.getTables();
    	//int index=0;
    	//操作word中的表格
    	for (int i = 0; i < tables.size(); i++) {
    		//只处理行数大于等于2的表格,且不循环表头
    		XWPFTable table = tables.get(i);
    		List<String[]> list = (List<String[]>) mapList.get(i);
    		if (null != list && 0 < list.size()){
    			//logger.info("CrtWordUtils--生成word中表格第"+(i+1)+"个表格开始");
    			//logger.info("CrtWordUtils--生成word中表格第"+(i+1)+"个表格结束");
    			if(i == 3){//--i:第i个表格
    				insertTable_quality(table,list,i);
	                for (int c=0;c<list.size();c++){ //合并列
	                	mergeColumnsCellVertically(table,c+2,0,1);
	                }
    			}
    		}
    		//index++;
    	}
    }
    
    /**
     * 此处做了特殊处理 如果文本段落中出现有需要换行, replaceTabStr对应下面的数据格式
     * 
     * List<Object[]> resultBydeptList = baseMapList.get("resultBydeptList");
	        StringBuilder sbResultStr = new StringBuilder();
	        for (Iterator iter = resultBydeptList.iterator(); iter.hasNext();) {
	        	Object[] objArr = (Object[])iter.next();
	        	Object yearResultStr = objArr[2];
	        	if(yearResultStr != null){
	        		sbResultStr.append(objArr[0]).append(objArr[1]).append("replaceTabStr").append(objArr[2]).append("replaceTabStr");
	        	}
	        }
	        data.put("${paragraph1_yearresult}", sbResultStr.toString().isEmpty()?"无":sbResultStr.toString());
     * 
     * 替换段落文本
     * @param document docx解析对象
     * @param textMap 需要替换的信息集合
     */
    public static void changeText(BaseXWPFDocument document, Map<String, Object> textMap){
        //获取段落集合
        List<XWPFParagraph> paragraphs = document.getParagraphs();
        for (XWPFParagraph paragraph : paragraphs) {
            //判断此段落是否需要进行替换
            String text = paragraph.getText();
            if(checkText(text)){
                List<XWPFRun> runs = paragraph.getRuns();
                for (int i = 0;i<runs.size();i++) {
                    //替换模板原来位置
                    Object obstr = changeValue(text, textMap);
                    // logger.info("CrtWordUtils--段落信息..."+runs.get(i).toString());
                    //分段显示的情况
                	String[] values = obstr.toString().split("replaceTabStr");
                	if(values.length > 1) {
                		runs.get(i).setText(values[0],0);
                		for (int j = 1; j < values.length; j++) {
                		       //存在分段则新建一个run
                			XWPFRun newrun = paragraph.insertNewRun(j);
                			newrun.getCTR().setRPr(runs.get(i).getCTR().getRPr());//copy样式
                			newrun.addBreak();//换行
                			newrun.getCTR().addNewTab();//缩进
                			newrun.setText(values[j]);
                		}
                		break;
                	}else{
                		runs.get(i).setText(obstr.toString().replace("replaceTabStr", ""),0);
                	}
                    if(i > 0){
                    	runs.get(i).setText("",0);
                    }
                }
            }
        }
    }

    /**
     * 为表格插入数据,行数不够添加新行
     * @param table 需要插入数据的表格
     * @param daList 表格的插入数据
     * @param type 表格类型:0-第一个表格 以此类推
     */
    public static void insertTable(XWPFTable table, List<String[]> daList,Integer type){
		//创建行和创建需要的列(有行样式要求的)
		for(int i = 1; i < daList.size(); i++){
			//添加一个新行
			int startRow = type.equals(2)?3:2;//  第二个表格  插入新行从3开始 其他2开始
			int rowPos = startRow;  //rowPos 的作用是获取新行的下一行,便于复制新行的样式
			insertNewRow(table,table.getRow(rowPos),rowPos+1);
			//logger.info("CrtWordUtils--创建表格行成功");
		}
		//创建行,根据需要插入的数据添加新行,不处理表头
		for(int i = 0; i < daList.size(); i++){
			int startRow = type.equals(2)?3:2;//  第二个表格  插入新行从3开始 其他2开始
			int rowPos = startRow;  //rowPos 的作用是获取新行的下一行,便于复制新行的样式
			List<XWPFTableCell> cells = table.getRow(i+rowPos).getTableCells();
			//logger.info("CrtWordUtils--表格中每个单元格插入元素开始");
			for(int j = 0; j < cells.size(); j++){
				XWPFTableCell cell02 = cells.get(j);
				CTTc ctTc = cell02.getCTTc(); 
				// here is need to change... 设置边框
				CTTcPr tcPr = ctTc.addNewTcPr();
				CTTcBorders border = tcPr.addNewTcBorders();
				border.addNewRight().setVal(STBorder.SINGLE);
				border.addNewLeft().setVal(STBorder.SINGLE);
				border.addNewBottom().setVal(STBorder.SINGLE);
				//设置字体居中
				tcPr.addNewVAlign().setVal(STVerticalJc.CENTER);
				ctTc.getPList().get(0).addNewPPr().addNewJc().setVal(STJc.CENTER);
				if(type.equals(2) && daList.get(i)[j].equals("否")){//内容显示红色
					//logger.info("CrtWordUtils--表格3中开始特殊处理");
					cell02.removeParagraph(0);
					XWPFParagraph newPara = new XWPFParagraph(cell02.getCTTc().addNewP(), cell02);                                                                                                                               
                    XWPFRun run=newPara.createRun();                       
                    newPara.setAlignment(ParagraphAlignment.CENTER);
                    run.getCTR().addNewRPr().addNewColor().setVal("FF0000");/**FF0000红色*/                               
                    run.setText(daList.get(i)[j]);    
                    cell02.setColor("cc99ff");
				}else{
					cell02.setText(daList.get(i)[j]);
				}
			}
		}
    }
    /**
     * 为表格插入数据,行数不够添加新行
     * @param table 需要插入数据的表格
     * @param daList 表格的插入数据
     * @param type 表格类型:0-第一个表格 以此类推
     */
    public static void insertTable_quality(XWPFTable table, List<String[]> daList,Integer type){
    	//创建行和创建需要的列
    	for(int i = 1; i < daList.size(); i++){
    		//添加一个新行
    		insertNewRow(table,table.getRow(2),3);
    		//logger.info("CrtWordUtils--创建表格行成功");
    	}
    	//创建行,根据需要插入的数据添加新行,不处理表头
    	for(int i = 0; i < daList.size(); i++){
    		List<XWPFTableCell> cells = table.getRow(i+2).getTableCells();
    		//String [] rowdatas  = daList.get(i);
    		//logger.info("CrtWordUtils--表格中每个单元格插入元素开始");
    		for(int j = 0; j < cells.size(); j++){
    			XWPFTableCell cell02 = cells.get(j);
    			CTTc ctTc = cell02.getCTTc(); 
    			// here is need to change... 设置边框
    			CTTcPr tcPr = ctTc.addNewTcPr();
    			CTTcBorders border = tcPr.addNewTcBorders();
    			border.addNewRight().setVal(STBorder.SINGLE);
    			border.addNewLeft().setVal(STBorder.SINGLE);
    			border.addNewBottom().setVal(STBorder.SINGLE);
    			//设置字体居中
    			tcPr.addNewVAlign().setVal(STVerticalJc.CENTER);
    			ctTc.getPList().get(0).addNewPPr().addNewJc().setVal(STJc.CENTER);
    			//if(type.equals(0)&&j==1){
    			if(type.equals(0)&&j==1&&daList.get(i)[5].equals("0")){
    				cell02.removeParagraph(0);
    				XWPFParagraph newPara = new XWPFParagraph(cell02.getCTTc().addNewP(), cell02);                                                                                                                               
    				XWPFRun run=newPara.createRun();                       
    				newPara.setAlignment(ParagraphAlignment.CENTER);
    				run.getCTR().addNewRPr().addNewColor().setVal("008000");/**#008000绿色*/                               
    				run.setText(daList.get(i)[j]); 
    			}else{
    				cell02.setText(daList.get(i)[j]);
    			}
    		}
    	}
    }

    /**
     * 判断文本中是否包含$
     * @param text 文本
     * @return 包含返回true,不包含返回false
     */
    public static boolean checkText(String text){
        boolean check  =  false;
        if(text.indexOf('$')!= -1){
            check = true;
        }
        return check;
    }

    /**
     * 匹配传入信息集合与模板
     * @param value 模板需要替换的区域
     * @param textMap 传入信息集合
     * @return 模板需要替换区域信息集合对应值
     */
    public static Object changeValue(String value, Map<String, Object> textMap){
        Set<Map.Entry<String, Object>> textSets = textMap.entrySet();
        Object valu = value;
        for (Map.Entry<String, Object> textSet : textSets) {
            String key = textSet.getKey();
            if(value.indexOf(key)!= -1){
                valu = String.valueOf(valu).replace("$"+textSet.getKey().substring(1), textSet.getValue().toString());
            }
        }
        return valu;
    }

    /**
     * 合并行
     * @param table
     * @param col 需要合并的列
     * @param fromRow 开始行
     * @param toRow 结束行
     */
    public static void mergeCellVertically(XWPFTable table, int col, int fromRow, int toRow) {
        for(int rowIndex = fromRow; rowIndex <= toRow; rowIndex++){
            CTVMerge vmerge = CTVMerge.Factory.newInstance();
            if(rowIndex == fromRow){
                vmerge.setVal(STMerge.RESTART);
            } else {
                vmerge.setVal(STMerge.CONTINUE);
            }
            XWPFTableCell cell = table.getRow(rowIndex).getCell(col);
            CTTcPr tcPr = cell.getCTTc().getTcPr();
            if (tcPr != null) {
                tcPr.setVMerge(vmerge);
            } else {
                tcPr = CTTcPr.Factory.newInstance();
                tcPr.setVMerge(vmerge);
                cell.getCTTc().setTcPr(tcPr);
            }
        }
    }
    /**
     * 合并列
     * @param table
     * @param col 需要合并的列
     * @param fromRow 开始行
     * @param toRow 结束行
     */
    public static void mergeColumnsCellVertically(XWPFTable table, int rownum, int fromCol, int toCol) {
    	XWPFTableRow row = table.getRow(rownum);
    	for(int rowIndex = fromCol; rowIndex <= toCol; rowIndex++){
    		CTHMerge hMerge = CTHMerge.Factory.newInstance();
    		if(rowIndex == fromCol){
    			hMerge.setVal(STMerge.RESTART);
    		} else {
    			hMerge.setVal(STMerge.CONTINUE);
    		}
    		XWPFTableCell cell = row.getCell(rowIndex);
    		CTTcPr tcPr = cell.getCTTc().getTcPr();
    		if (tcPr != null) {
    			tcPr.setHMerge(hMerge);
    		} else {
    			tcPr = CTTcPr.Factory.newInstance();
    			tcPr.setHMerge(hMerge);
    			cell.getCTTc().setTcPr(tcPr);
    		}
    	}
    }
    /**
     * 获取需要合并单元格的下标
     * @return
     */
    public static List<Integer[]> startEnd(List<String[]> daList){
        List<Integer[]> indexList = new ArrayList();
        List<String> list = new ArrayList();
        for (int i=0;i<daList.size();i++){
            list.add(daList.get(i)[0]);
        }
        Map<Object, Integer> tm = new HashMap();
        for (int i=0;i<daList.size();i++){
            if (!tm.containsKey(daList.get(i)[0])) {
                tm.put(daList.get(i)[0], 1);
            } else {
                int count = tm.get(daList.get(i)[0]) + 1;
                tm.put(daList.get(i)[0], count);
            }
        }
        for (Map.Entry<Object, Integer> entry : tm.entrySet()) {
            String key = entry.getKey().toString();
            if (list.indexOf(key) != (-1)){
                Integer[] index = new Integer[2];
                index[0] = list.indexOf(key);
                index[1] = list.lastIndexOf(key);
                indexList.add(index);
            }
        }
        return indexList;
    }
    
    /**
     * 插入新行 同时复制首行的样式 
     * table 操作的表格
     * copyRow 表头下面的行
     * newRowIndex  copyRow该行下面的行的索引,复制copyRow该行的样式
     * 
     * */
    public static XWPFTableRow insertNewRow(XWPFTable table,XWPFTableRow copyRow,Integer newRowIndex){
    	XWPFTableRow targetRow = table.insertNewTableRow(newRowIndex);
    	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());
    			}
    		}
			
		}
    	return targetRow;
    }
    
    /**
     * 根据图片类型,取得对应的图片类型代码
     * @param picType
     * @return int
     */
    private static int getPictureType(String picType){
        int res = BaseXWPFDocument.PICTURE_TYPE_PICT;
        if(picType != null){
            if(picType.equalsIgnoreCase("png")){
                res = BaseXWPFDocument.PICTURE_TYPE_PNG;
            }else if(picType.equalsIgnoreCase("dib")){
                res = BaseXWPFDocument.PICTURE_TYPE_DIB;
            }else if(picType.equalsIgnoreCase("emf")){
                res = BaseXWPFDocument.PICTURE_TYPE_EMF;
            }else if(picType.equalsIgnoreCase("jpg") || picType.equalsIgnoreCase("jpeg")){
                res = BaseXWPFDocument.PICTURE_TYPE_JPEG;
            }else if(picType.equalsIgnoreCase("wmf")){
                res = BaseXWPFDocument.PICTURE_TYPE_WMF;
            }
        }
        return res;
    }
    
    /**
     * 将输入流中的数据写入字节数组
     * @param in
     * @return
     */
    public static byte[] inputStream2ByteArray(InputStream in, boolean isClose){
        byte[] byteArray = null;
        try {
            int total = in.available();
            byteArray = new byte[total];
            in.read(byteArray);
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            if(isClose){
                try {
                    in.close();
                } catch (Exception e2) {
                    System.out.println("关闭流失败");
                }
            }
        }
        return byteArray;
    }
    
    /**
     * 遍历表格
     * @param rows 表格行对象
     * @param textMap 需要替换的信息集合
     */
    public static void eachTable(BaseXWPFDocument document, List<XWPFTableRow> rows , Map<String, Object> 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) {
                            Object ob = changeValue(run.toString(), textMap);
                            if (ob instanceof String){
                                run.setText((String)ob,0);
                            }else if (ob instanceof Map){
                               /* 此处本想实现表格中插入图片 ,但是失效 所以在89行中自行处理 -^^-
                                * run.setText("",0);
                                Map pic = (Map)ob;
                                int width = Integer.parseInt(pic.get("width").toString());
                                int height = Integer.parseInt(pic.get("height").toString());
                                int picType = getPictureType(pic.get("type").toString());
                                byte[] byteArray = (byte[]) pic.get("content");
                                ByteArrayInputStream byteInputStream = new ByteArrayInputStream(byteArray);
                                try {
                                    String ind = document.addPictureData(byteInputStream,picType);
                                    document.createPicture(Integer.valueOf(ind), width , height,paragraph);
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }*/
                            }
                        }
                    }
                }
            }
        }
    }
    /**
     * 关闭输入流
     *
     * @param is
     */
    private void close(InputStream is) {
        if (is != null) {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 关闭输出流
     *
     * @param os
     */
    private void close(OutputStream os) {
        if (os != null) {
            try {
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

Main.java

package word;

import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.imageio.ImageIO;

import org.apache.poi.util.IOUtils;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;

public class Main {

    public static void main(String[] args) throws Exception {
        //需要进行文本替换的信息
        Map<String, Object> data = new HashMap<String, Object>();
        data.put("${date}", "2020");
        
        //需要进行动态生成的信息
        List<Object> mapList = new ArrayList<Object>();

        //第一个动态生成的数据列表
        List<String[]> list01 = new ArrayList<String[]>();
        list01.add(new String[]{"张三","男","23"});
        list01.add(new String[]{"李四","女","24"});
        list01.add(new String[]{"王五","女","25"});
        
        //第二个动态生成的数据列表
        List<String[]> list02 = new ArrayList<String[]>();
        list02.add(new String[]{"张三","语文","134"});
        list02.add(new String[]{"张三","数学","141"});
        list02.add(new String[]{"张三","英语","132"});
        list02.add(new String[]{"李四","语文","131"});
        list02.add(new String[]{"李四","数学","131"});
        list02.add(new String[]{"李四","英语","134"});
        list02.add(new String[]{"王五","语文","136"});
        list02.add(new String[]{"王五","数学","145"});
        list02.add(new String[]{"王五","英语","134"});

        //第三个动态生成的数据列表
	    List<String[]> list03 = new ArrayList<String[]>();
	    list03.add(new String[]{"甲老师","是","否","否"});
	    list03.add(new String[]{"乙老师","否","是","否"});
	    list03.add(new String[]{"丙老师","否","是","否"});
	    list03.add(new String[]{"丁老师","是","否","否"});
        
        //第四个动态生成的数据列表
        List<String[]> list04 = new ArrayList<String[]>();
        list04.add(new String[]{"语文","语文","英语","数学"});
        list04.add(new String[]{"英语","英语","语文","数学"});

        mapList.add(list01);
        mapList.add(list02);
        mapList.add(list03);
        mapList.add(list04);
       
        BaseXWPFDocument doc = CrtWordUtils.changWord("D:/test.docx",data,mapList);
        FileOutputStream fopts = new FileOutputStream("D:/stu.doc");
        
        
        /**--------此处实在文档的最后插入一张图片       可尝试在指定的段落中插入(此处未实现) ------*/
        FileInputStream fis = new FileInputStream("D:/1.png");
        byte[] byteArray = IOUtils.toByteArray(fis);
        ByteArrayInputStream bais = new ByteArrayInputStream(byteArray);
        ImageIO.read(bais);
        
        XWPFParagraph paragraph = doc.createParagraph();
        XWPFRun run2 = paragraph.createRun();
        /*//原始值
        int width = Units.toEMU(image.getWidth());
        int height = Units.toEMU(image.getHeight());*/
        
        //自定义值
        int width = Units.toEMU(360);
        int height = Units.toEMU(360);
        
        run2.addPicture(new FileInputStream("D:/1.png"), BaseXWPFDocument.PICTURE_TYPE_PNG, "test",
                width, height);
        /**--------此处实在文档的最后插入一张图片------*/
        
        doc.write(fopts);
        fopts.close();
    }

}

最终生成的文档(方便观看,多页展示了-^^-)

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值